我如何在JavaScript中检测互联网连接是否离线?
我如何在JavaScript中检测互联网连接是否离线?
几乎所有主流浏览器现在都支持 window.navigator.onLine
属性以及相应的 online
和 offline
窗口事件。运行以下代码片段进行测试:
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.onLine
是false
,您保证没有互联网连接。
然而,如果它是true
(或者你收到一个online
事件),它只意味着系统连接到一些网络,最多。例如,它并不意味着您有Internet访问权。要检查这一点,您仍需要使用其他答案中描述的解决方案之一。
我最初打算将此作为对Grant Wagner的回答的更新发布,但觉得可能太大了,特别是考虑到2014年的更新已经不是他写的。
online
只是表示您有某种连接,而不是表示您具有互联网访问权限。我抓住这个机会在我的回答中放了一段代码片段来测试它。 - Didier L通过进行失败的XHR请求,您可以确定连接是否丢失。
标准方法是尝试重试请求几次。如果仍然无法成功,警告用户检查连接,并优雅地失败。
附注:将整个应用程序置于“离线”状态可能会导致处理状态方面出现许多容易出错的工作.. 无线连接可能会存在不稳定性等问题。因此,最好只是优雅地失败,保留数据并提醒用户..让他们最终修复连接问题(如果有),并以相当宽容的方式继续使用您的应用程序。
附注:您可以检查可靠站点(例如Google)的连通性,但这可能不完全有用,因为与只尝试自己的请求相比,虽然Google可能可用,但您自己的应用程序可能不可用,您仍需处理自己的连接问题。尝试向google发送一个ping请求是确认互联网连接本身是否中断的好方法,因此,如果这些信息对您有用,则可能值得一试。
注意事项: 发送Ping可以通过与进行任何双向Ajax请求相同的方式实现,但是在这种情况下向Google发送Ping会遇到一些挑战。首先,我们将遇到通常在进行Ajax通信时遇到的跨域问题。其中一个选项是设置服务器代理,在其中实际上ping
Google(或任何网站),并将Ping的结果返回给应用程序。这是一个进退两难,因为如果互联网连接实际上是问题所在,我们将无法访问服务器,而且如果连接问题仅存在于我们自己的域中,我们也无法区分差异。其他跨域技术可以尝试,例如在页面中嵌入指向Google.com的iframe,然后轮询iframe的成功/失败(检查内容等)。嵌入图像可能无法告诉我们任何东西,因为我们需要从通信机制中获得有用的响应,以便就当前状况得出良好结论。因此,确定整个互联网连接状态可能比得上它带来的麻烦还要多。您必须权衡这些选项以适用于您特定的应用程序。
navigator.onLine
明显是目前最好的解决方案,因为它已经支持跨浏览器了(参见 http://caniuse.com/#feat=online-status)。 - Stijn de WittIE 8将支持 window.navigator.onLine 属性。
但是当然,这不能解决其他浏览器或操作系统的问题。我预测其他浏览器供应商会考虑提供该属性,鉴于在Ajax应用程序中了解在线/离线状态的重要性。
在此之前,可以使用XHR或Image()
或<img>
请求来提供接近所需功能的东西。
更新(2014/11/16)
主流浏览器现在都支持这个属性,但你的结果可能会有所不同。
引用自Mozilla文档:
在Chrome和Safari中,如果浏览器无法连接到本地区域网络(LAN)或路由器,则处于离线状态;所有其他情况均返回
true
。因此,当它返回false
值时,您可以假定浏览器处于离线状态,但您不能假定真值必然意味着浏览器可以访问互联网。您可能会得到错误的结果,例如在计算机运行具有虚拟以太网适配器的虚拟化软件的情况下。因此,如果您确实想确定浏览器的在线状态,则应开发其他检查方法。在Firefox和Internet Explorer中,将浏览器切换到离线模式会发送
false
值。所有其他情况均返回true
值。
if (navigator.onLine) {
alert('online');
} else {
alert('offline');
}
查看{{link1:onLine
的基本用法}}
有几种方法可以做到这一点:
img
中放置onerror
,例如:<img src="http://www.example.com/singlepixel.gif" onerror="alert('Connection dead');" />
。如果源图像移动/重命名,则此方法也可能失败,并且通常比ajax选项差。
因此,有几种不同的方法可以尝试检测到这一点,但没有完美的方法,在无法跳出浏览器沙箱并直接访问用户的网络连接状态的情况下,它们似乎是最佳选择。
正如olliej所说,使用navigator.onLine
浏览器属性比发送网络请求更可取,并且根据developer.mozilla.org/En/Online_and_offline_events的说明,即使是旧版本的Firefox和IE也支持它。
最近,WHATWG已经指定了添加online
和offline
事件,以便在需要对navigator.onLine
更改做出反应时使用。
请注意Daniel Silveira发布的链接,该链接指出仅依赖这些信号/属性与服务器同步并不总是一个好主意。
window.navigator.onLine
这就是你要找的内容,但还需要补充一些东西。首先,如果你想一直检查应用程序中的某些东西(比如看看用户是否突然离线,在这种情况下大部分时间都是正确的),那么你需要添加事件监听器来检测任何更改。为了检查用户是否离线,你可以执行以下操作:
window.addEventListener("offline",
()=> console.log("No Internet")
);
用于检查是否在线:
window.addEventListener("online",
()=> console.log("Connected Internet")
);
onLine
。浏览器对于在线状态的定义有很大不同。请参考 https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine。 - Andreas Baumgarterror
回调函数,如果请求失败就会触发。如果textStatus
等于字符串"timeout",那么很可能是连接中断了。function (XMLHttpRequest, textStatus, errorThrown) {
// typically only one of textStatus or errorThrown
// will have info
this; // the options for this ajax request
}
根据文档:
Error: 如果请求失败,将调用一个函数。函数传入三个参数: 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!');
}
}
});
HTML5应用缓存API指定了navigator.onLine。该属性目前在IE8测试版、WebKit(例如Safari)每夜构建版本中提供,并且已经在Firefox 3中得到支持。
navigator.onLine
仍将返回 true
。 - TheCarver通过向您的域发出ajax调用是检测您是否离线的最简单方法。
$.ajax({
type: "HEAD",
url: document.location.pathname + "?param=" + new Date(),
error: function() { return false; },
success: function() { return true; }
});
这只是为了让您理解概念,需要改进。
例如,错误=404仍应该意味着您在线。