如何在JavaScript中检测Internet连接是否脱机?
您可以通过发出失败的XHR请求来确定连接丢失.
标准方法是重试请求几次.如果未通过,则提醒用户检查连接,并正常失败.
旁注:将整个应用程序置于"离线"状态可能会导致很多容易出错的处理状态工作..无线连接可能会来来去去等等.所以你最好的选择可能就是优雅地失败,保留数据,并警告用户..允许他们最终解决连接问题,如果有的话,并继续使用你的应用程序与相当多的宽恕.
旁注:您可以检查一个像google这样可靠的网站进行连接,但这可能并不完全有用,因为只是尝试发出自己的请求,因为虽然谷歌可能可用,但您自己的应用可能不是,而您仍然会必须处理自己的连接问题.尝试向谷歌发送ping将是确认互联网连接本身已关闭的好方法,所以如果这些信息对您有用,那么它可能是值得的.
旁注:发送Ping可以通过与制作任何类型的双向ajax请求相同的方式实现,但是在这种情况下向谷歌发送ping会带来一些挑战.首先,我们遇到了与进行Ajax通信时通常遇到的相同的跨域问题.一种选择是设置服务器端代理,其中我们实际上ping
谷歌(或任何网站),并将ping的结果返回给应用程序.这是一个捕获22因为如果互联网连接实际上是问题,我们将无法访问服务器,如果连接问题仅在我们自己的域上,我们将无法区分.可以尝试其他跨域技术,例如,在您的页面中嵌入指向google.com的iframe,然后轮询iframe的成功/失败(检查内容等).嵌入图像可能并不能真正告诉我们什么,因为我们需要来自通信机制的有用响应,以便对正在发生的事情得出一个好的结论.因此,再次确定整个互联网连接的状态可能比它的价值更麻烦.您必须为特定应用加重这些选项.
IE 8将支持window.navigator.onLine属性.
但当然这对其他浏览器或操作系统没有帮助.我预测,鉴于了解Ajax应用程序中的在线/离线状态的重要性,其他浏览器供应商也将决定提供该属性.
在此之前,无论是XHR或Image()
或请求可以提供一些接近你想要的功能.
更新(2014/11/16)
主流浏览器现在支持此属性,但您的结果会有所不同.
来自Mozilla文档的引用:
在Chrome和Safari中,如果浏览器无法连接到局域网(LAN)或路由器,则它处于脱机状态; 所有其他条件都返回
true
.因此,虽然您可以假设浏览器在返回false
值时处于脱机状态,但您不能认为真值必然意味着浏览器可以访问Internet.您可能会收到误报,例如计算机运行的虚拟化软件具有始终"连接"的虚拟以太网适配器.因此,如果您确实想确定浏览器的在线状态,则应开发其他检查方法.在Firefox和Internet Explorer中,将浏览器切换到脱机模式会发送一个
false
值.所有其他条件都返回一个true
值.
有很多方法可以做到这一点:
AJAX请求到您自己的网站.如果该请求失败,则很可能是连接出错.在JQuery的文件有一个部分处理失败的AJAX请求.执行此操作时请注意同源策略,这可能会阻止您访问域外的站点.
你可以放onerror
一个img
,像
如果移动/重命名源图像,此方法也可能失败,并且通常是ajax选项的劣质选择.
所以有几种不同的方法可以尝试和检测这一点,没有一个完美,但由于缺乏跳出浏览器沙箱并直接访问用户的网络连接状态的能力,它们似乎是最好的选择.
if(navigator.onLine){ alert('online'); } else { alert('offline'); }
几乎所有的主流浏览器都支持的window.navigator.onLine
特性,以及相应online
和offline
窗口事件:
window.addEventListener('online', () => console.log('came online')); window.addEventListener('offline', () => console.log('came offline'));
尝试在离线/在线模式下设置系统或浏览器,并检查控制台或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
(或者你得到一个offline
事件),你可以保证没有互联网连接.
true
但是,如果它(或者你得到一个online
事件),它只表示系统最多连接到某个网络.例如,这并不意味着您可以访问Internet.要检查这一点,您仍然需要使用其他答案中描述的解决方案之一.
我最初打算将此作为Grant Wagner答案的更新发布,但这似乎太过于编辑,特别是考虑到2014年更新已经不是他的了.
HTML5应用程序缓存API指定了navigator.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 }
来自doc:
错误:请求失败时要调用的函数.该函数传递三个参数: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已指定添加online
和offline
事件,以防您需要对navigator.onLine
更改做出反应.
另请注意Daniel Silveira发布的链接,该链接指出依赖这些信号/属性与服务器同步并不总是一个好主意.
我必须为经常在学校工作的客户制作一个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应该仍然表示您在线
我认为这是一种非常简单的方法。
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;