检测网络连接是否离线?

如何在JavaScript中检测Internet连接是否离线?

335025 次浏览

你可以通过XHR请求失败来确定连接是否丢失。

标准的方法是重试请求几次。如果它没有通过,提醒用户检查连接,和不优雅的

将整个应用程序置于“脱机”状态可能会导致大量易出错的处理状态工作。无线连接可能来来去去,等等。因此,最好的办法可能是优雅地失败,保存数据,并提醒用户。允许他们最终解决连接问题(如果有的话),并在一定程度上原谅他们继续使用你的应用。

旁注:你可以检查一个可靠的网站,如谷歌的连接性,但这可能不是完全有用,因为只是尝试自己的请求,因为谷歌可能是可用的,你自己的应用程序可能不是,你仍然要处理自己的连接问题。尝试向谷歌发送ping信息是确认网络连接本身已中断的好方法,因此如果该信息对您有用,那么可能值得费心。

旁注: 发送Ping可以用同样的方式实现,你会做出任何类型的双向ajax请求,但发送一个ping到谷歌,在这种情况下,会带来一些挑战。首先,我们会遇到在进行Ajax通信时通常会遇到的跨域问题。一种选择是设置一个服务器端代理,其中我们实际上ping谷歌(或任何站点),并将ping的结果返回到应用程序。这是一个第二十二条军规,因为如果互联网连接确实是问题,我们将无法到达服务器,如果连接问题只在我们自己的域上,我们将无法区分。可以尝试其他跨域技术,例如,在您的页面中嵌入指向google.com的iframe,然后轮询iframe的成功/失败(检查内容等)。嵌入图像可能并不能真正告诉我们任何东西,因为我们需要从沟通机制中得到有用的回应,才能对正在发生的事情得出一个好的结论。因此,确定整个互联网连接的状态可能比它的价值更麻烦。您必须为您的特定应用程序权衡这些选项。

有很多方法可以做到这一点:

  • AJAX请求到您自己的网站。如果请求失败,很有可能是连接有问题。JQuery文档有一个关于处理失败的AJAX请求的章节。这样做时要注意同源策略,它可能会阻止你访问域外的网站。
  • 你可以在img中放入onerror,比如<img src="http://www.example.com/singlepixel.gif" onerror="alert('Connection dead');" />

如果源图像被移动/重命名,此方法也可能失败,并且通常是一个不如ajax选项的选择。

因此,有几种不同的方法来尝试和检测这种情况,没有一种是完美的,但在没有跳出浏览器沙箱并直接访问用户的网络连接状态的能力的情况下,它们似乎是最好的选择。

IE 8将支持window.navigator.onLine属性。

但当然,这对其他浏览器或操作系统没有帮助。考虑到了解Ajax应用程序中的在线/离线状态的重要性,我预计其他浏览器供应商也将决定提供该属性。

在此之前,XHR或Image()<img>请求都可以提供接近你想要的功能。

更新(2014/11/16)

大多数浏览器现在都支持这个属性,但结果会有所不同。

引用自Mozilla的文档:

在Chrome和Safari浏览器中,如果浏览器无法连接到局域网(LAN)或路由器,就会处于离线状态;所有其他条件返回true。因此,虽然你可以假设浏览器在返回false值时处于离线状态,但你不能假设一个真值就一定意味着浏览器可以访问互联网。你可能会得到误报,比如在计算机运行虚拟化软件的情况下,虚拟以太网适配器总是“连接”。因此,如果您真的想确定浏览器的在线状态,您应该开发额外的检查方法。

在Firefox和Internet Explorer中,将浏览器切换到离线模式会发送false值。所有其他条件返回true值。

HTML5应用程序缓存API指定导航器。onLine,目前在IE8测试版中可用,WebKit(例如。Safari)的夜间运行,并且已经在Firefox 3中得到支持

你可以使用$ . ajax ()error回调函数,它在请求失败时触发。如果textStatus等于字符串"timeout",则可能意味着连接中断:

function (XMLHttpRequest, textStatus, errorThrown) {
// typically only one of textStatus or errorThrown
// will have info
this; // the options for this ajax request
}

医生:

错误:请求时调用的函数 失败。函数被传递了3个 参数:XMLHttpRequest对象 描述错误类型的字符串 这是可选的 异常对象,如果发生。 第二个可能的值 参数(除null外)为"timeout", "error", "notmodified"和 “parsererror”。这是一个Ajax事件

例如:

 $.ajax({
type: "GET",
url: "keepalive.php",
success: function(msg){
alert("Connection active!")
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
if(textStatus == 'timeout') {
alert('Connection seems dead!');
}
}
});

正如olliej所说,使用navigator.onLine浏览器属性比发送网络请求更可取,因此使用developer.mozilla.org/En/Online_and_offline_events,它甚至被旧版本的Firefox和IE支持。

最近,WHATWG指定了onlineoffline事件的添加,以防你需要对navigator.onLine的变化做出反应。

请注意Daniel Silveira发布的链接,他指出依赖这些信号/属性与服务器同步并不总是一个好主意。

下面是我拥有的一个辅助实用程序片段。这是带名称空间的javascript:

network: function() {
var state = navigator.onLine ? "online" : "offline";
return state;
}

你应该使用这个方法检测,否则发射一个'替代'的方式来做这件事。这将是我们所需要的全部。其他的方法是hack。

我的方式。

<!-- the file named "tt.jpg" should exist in the same directory -->


<script>
function testConnection(callBack)
{
document.getElementsByTagName('body')[0].innerHTML +=
'<img id="testImage" style="display: none;" ' +
'src="tt.jpg?' + Math.random() + '" ' +
'onerror="testConnectionCallback(false);" ' +
'onload="testConnectionCallback(true);">';


testConnectionCallback = function(result){
callBack(result);


var element = document.getElementById('testImage');
element.parentNode.removeChild(element);
}
}
</script>


<!-- usage example -->


<script>
function myCallBack(result)
{
alert(result);
}
</script>


<a href=# onclick=testConnection(myCallBack);>Am I online?</a>
 if(navigator.onLine){
alert('online');
} else {
alert('offline');
}

我不得不为一个与学校有很多合作的客户制作一个web应用程序(基于ajax),这些学校的互联网连接经常不好,我使用这个简单的功能来检测是否有连接,工作得非常好!

我使用CodeIgniter和Jquery:

function checkOnline() {
setTimeout("doOnlineCheck()", 20000);
}


function doOnlineCheck() {
//if the server can be reached it returns 1, other wise it times out
var submitURL = $("#base_path").val() + "index.php/menu/online";


$.ajax({
url : submitURL,
type : "post",
dataType : "msg",
timeout : 5000,
success : function(msg) {
if(msg==1) {
$("#online").addClass("online");
$("#online").removeClass("offline");
} else {
$("#online").addClass("offline");
$("#online").removeClass("online");
}
checkOnline();
},
error : function() {
$("#online").addClass("offline");
$("#online").removeClass("online");
checkOnline();
}
});
}

对域的ajax调用是检测您是否脱机的最简单方法

$.ajax({
type: "HEAD",
url: document.location.pathname + "?param=" + new Date(),
error: function() { return false; },
success: function() { return true; }
});

这只是给大家一个概念,还需要改进。

例如,error=404仍然意味着您在线

我正在寻找一种客户端解决方案,以检测互联网是否宕机或服务器是否宕机。我发现的其他解决方案似乎总是依赖于第三方脚本文件或图像,这对我来说似乎不像是经得起时间的考验。将来可能会更改外部托管脚本或映像,从而导致检测代码失败。

我找到了一种方法,通过查找带有404代码的xhrStatus来检测它。此外,我使用JSONP绕过CORS限制。如果状态码不是404,则表明网络连接无法工作。

$.ajax({
url:      'https://www.bing.com/aJyfYidjSlA' + new Date().getTime() + '.html',
dataType: 'jsonp',
timeout:  5000,


error: function(xhr) {
if (xhr.status == 404) {
//internet connection working
}
else {
//internet is down (xhr.status == 0)
}
}
});

我认为这是一个非常简单的方法。

var x = confirm("Are you sure you want to submit?");
if (x) {
if (navigator.onLine == true) {
return true;
}
alert('Internet connection is lost');
return false;
}
return false;

对于两种不同的情况,有两个答案:-

  1. 如果你在网站上使用JavaScript(即;或任何前端部件) 最简单的方法是:

    <h2>The Navigator Object</h2>
    
    
    <p>The onLine property returns true if the browser is online:</p>
    
    
    <p id="demo"></p>
    
    
    <script>
    document.getElementById("demo").innerHTML = "navigator.onLine is " + navigator.onLine;
    </script>
    

    李< / p > < / >

  2. 但是如果你在服务器端使用js(即;节点等),您可以通过发出失败的XHR请求来确定连接丢失。

    标准的方法是重试请求几次。如果没有通过,提醒用户检查连接,并优雅地失败

请求头错误

$.ajax({
url: /your_url,
type: "POST or GET",
data: your_data,
success: function(result){
//do stuff
},
error: function(xhr, status, error) {


//detect if user is online and avoid the use of async
$.ajax({
type: "HEAD",
url: document.location.pathname,
error: function() {
//user is offline, do stuff
console.log("you are offline");
}
});
}
});

几乎所有主流浏览器现在支持window.navigator.onLine属性,以及相应的onlineoffline窗口事件。运行以下代码片段来测试它:

console.log('Initially ' + (window.navigator.onLine ? 'on' : 'off') + 'line');


window.addEventListener('online', () => console.log('Became online'));
window.addEventListener('offline', () => console.log('Became offline'));


document.getElementById('statusCheck').addEventListener('click', () => console.log('window.navigator.onLine is ' + window.navigator.onLine));
<button id="statusCheck">Click to check the <tt>window.navigator.onLine</tt> property</button><br /><br />
Check the console below for results:

尝试将您的系统或浏览器设置为离线/在线模式,并检查日志或window.navigator.onLine属性的值变化。

但是请注意Mozilla的文档引用的这句话:

在Chrome和Safari浏览器中,如果浏览器无法连接到局域网(LAN)或路由器,就会处于离线状态;所有其他条件返回true。所以当当浏览器返回false值时,您可以假设浏览器处于脱机状态你不能假设true值一定意味着浏览器可以访问互联网。你可能会得到误报,比如在计算机运行虚拟化软件的情况下,虚拟以太网适配器总是“连接”。因此,如果您真的想确定浏览器的在线状态,您应该开发额外的检查方法。

在Firefox和Internet Explorer中,将浏览器切换到离线模式会发送false值。在Firefox 41之前,所有其他条件返回true值;自Firefox 41以来,在OS X和Windows上,该值将遵循实际的网络连接。

(重点是我自己的)

这意味着如果window.navigator.onLinefalse(或者你得到一个offline事件),你保证没有互联网连接。

然而,如果它是true(或者你得到一个online事件),它充其量只意味着系统连接到某个网络。这并不意味着你可以上网。要检查这一点,您仍然需要使用其他答案中描述的解决方案之一。

我最初打算张贴这作为更新格兰特瓦格纳的回答,但这似乎是一个太多的编辑,特别是考虑到2014年的更新已经不是来自他

navigator.onLine这样的一些方法的问题是它们与一些浏览器和移动版本不兼容,一个帮助我很多的选项是使用经典的XMLHttpRequest方法,并预见到文件存储在缓存中的响应XMLHttpRequest.status大于200小于304的可能情况。

这是我的代码:

 var xhr = new XMLHttpRequest();
//index.php is in my web
xhr.open('HEAD', 'index.php', true);
xhr.send();


xhr.addEventListener("readystatechange", processRequest, false);


function processRequest(e) {
if (xhr.readyState == 4) {
//If you use a cache storage manager (service worker), it is likely that the
//index.php file will be available even without internet, so do the following validation
if (xhr.status >= 200 && xhr.status < 304) {
console.log('On line!');
} else {
console.log('Offline :(');
}
}
}
window.navigator.onLine

是你要找的,但这里要添加的东西很少,首先,如果它是你想要持续检查的应用程序上的一些东西(比如看看用户是否突然脱机,在这种情况下大多数时候是正确的,那么你也需要监听变化),为此你添加事件监听器到窗口来检测任何变化,为了检查用户是否脱机,你可以这样做:

window.addEventListener("offline",
()=> console.log("No Internet")
);

检查是否在线:

window.addEventListener("online",
()=> console.log("Connected Internet")
);

我知道这个问题已经被回答了,但我想补充我的10美分,解释什么是更好的,什么不是。

Window.navigator.onLine

我注意到一些回答提到了这个选项,但他们从来没有提到任何关于警告的内容。

这个选项包括使用&;__abc2 &;这是浏览器导航界面下的一个属性,大多数现代浏览器都可以使用。这真的不是一个可行的选择检查互联网可用性,因为首先it is browser centric和其次most browsers implement this property differently

在Firefox中:属性返回一个布尔值,其中true表示在线,false表示离线,但这里的警告是 “the value is only updated when the user follows links or when a script requests a remote page."因此,如果用户离线 你从js函数或脚本中查询属性,属性将会 总是返回true,直到用户遵循一个链接

在Chrome和Safari中:如果浏览器不能连接到局域网(LAN)或路由器,则浏览器离线;所有其他的 条件返回true。所以你可以假设浏览器是 离线时,当它返回false值时,不能假定为true 价值必然意味着浏览器可以访问互联网。你 可能会出现假阳性,比如电脑 运行的虚拟化软件是否具有虚拟以太网 始终“连接”的适配器。

上面的语句只是想让您知道,仅靠浏览器是无法判断的。所以基本上这个选项是不可靠的。

向自己的服务器资源发送请求

这包括向您自己的服务器资源发出HTTP请求,如果可以到达,则假设internet可用性,否则用户处于离线状态。对于这个选项有一些注意事项。
  1. 没有服务器可用性是100%依赖的,因此如果由于某种原因您的服务器不可达,它会错误地假设用户离线,而他们连接到互联网。
  2. 对同一资源的多个请求可以返回缓存的响应,这使得http响应结果不可靠。

如果你同意你的服务器一直在线,那么你可以选择这个选项。

下面是一个获取自己资源的简单代码片段:

// This fetches your website's favicon, so replace path with favicon url
// Notice the appended date param which helps prevent browser caching.
fetch('/favicon.ico?d='+Date.now())
.then(response => {
if (!response.ok)
throw new Error('Network response was not ok');


// At this point we can safely assume the user has connection to the internet
console.log("Internet connection available");
})
.catch(error => {
// The resource could not be reached
console.log("No Internet connection", error);
});

向第三方服务器资源发送请求

我们都知道CORS是个东西。

该选项包括向外部服务器资源发出HTTP请求,如果可以到达,则假设internet可用,否则用户处于脱机状态。主要的警告是跨地域资源共享作为一个限制。大多数信誉良好的网站会阻止CORS请求,但对一些网站来说,你可以随心所欲。

下面是一个获取外部资源的简单代码片段,与上面相同,但使用外部资源url:

// Firstly you trigger a resource available from a reputable site
// For demo purpose you can use the favicon from MSN website
// Also notice the appended date param which helps skip browser caching.
fetch('https://static-global-s-msn-com.akamaized.net/hp-neu/sc/2b/a5ea21.ico?d='+Date.now())
.then(response => {
// Check if the response is successful
if (!response.ok)
throw new Error('Network response was not ok');


// At this point we can safely say the user has connection to the internet
console.log("Internet available");
})
.catch(error => {
// The resource could not be reached
console.log("No Internet connection", error);
});

所以,最后对于我的个人项目,我选择了第二个选项,这涉及到请求自己的服务器资源,因为基本上有很多因素来判断是否有“互联网连接”。在用户的设备上,不仅仅是从你的网站容器,也从有限的浏览器api。

请记住,您的用户也可能处于某些网站或资源被封锁、禁止和不可访问的环境中,这反过来又会影响连接检查的逻辑。最好的选择是:

  • 尝试访问你自己服务器上的资源,因为这是你的用户环境(通常我使用网站的favicon,因为响应非常轻,它不经常更新)。
  • 如果没有连接到资源,简单地说“连接错误”;或“连接丢失”;当你需要通知用户,而不是假设一个宽泛的“没有互联网连接”;这取决于很多因素。

只要使用navigator.onLine,如果这是true,那么你是在线的,否则离线

您可以尝试,如果网络连接,这将返回true

function isInternetConnected(){return navigator.onLine;}

如何发送一个不透明的http请求到google.com与无cors?

    fetch('https://google.com', {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
mode: 'no-cors',
}).then((result) => {
console.log(result)
}).catch(e => {
console.error(e)
})

设置no-cors的原因是,即使在我的pc上取消网络连接时,我也收到了cors错误。所以不管有没有网络连接,我都被封锁了。添加no-cors使请求不透明,这显然似乎绕过cors,并允许我只是简单地检查我是否可以连接到谷歌。

供你参考:我在这里使用fetch来进行http请求。 https://www.npmjs.com/package/fetch < / p >