Answers:
您可以通过发出失败的XHR请求来确定连接丢失。
标准方法是重试几次请求。如果未通过,请警告用户检查连接,然后正常失败。
旁注:将整个应用程序置于“脱机”状态可能会导致很多容易出错的状态处理工作。无线连接可能会来去去等。因此,最好的选择是妥善地失败,保留数据,并警告用户..允许他们最终解决连接问题(如果有的话),并在相当多的宽恕下继续使用您的应用。
旁注:您可以检查像google这样的可靠网站的连通性,但这可能并不完全有用,仅是尝试提出自己的请求,因为尽管Google可能可用,但您自己的应用程序可能不可用,并且您仍将继续必须处理您自己的连接问题。尝试向Google发送ping通知是确认互联网连接本身已关闭的好方法,因此,如果该信息对您有用,那么麻烦就值得了。
旁注:发送Ping的方式可以与您发出任何双向双向Ajax请求的方式相同,但是在这种情况下,向Google发送Ping会带来一些挑战。首先,我们将遇到与进行Ajax通信时通常遇到的相同的跨域问题。一种选择是设置服务器端代理,我们实际上在其中ping
搜索Google(或任何站点),并将ping结果返回给应用程序。这是一个陷阱22因为如果实际上是Internet连接,我们将无法连接到服务器,并且如果连接问题仅在我们自己的域上,我们将无法分辨出差异。可以尝试其他跨域技术,例如,在您的网页中嵌入一个指向google.com的iframe,然后轮询该iframe的成功/失败(检查内容等)。嵌入图像可能并不能真正告诉我们任何信息,因为我们需要通信机制提供有用的响应,以便对正在发生的事情得出良好的结论。因此,再次确定整个Internet连接的状态可能比其价值更大。您必须为您的特定应用权衡这些选项。
IE 8将支持window.navigator.onLine属性。
但这当然对其他浏览器或操作系统没有帮助。鉴于了解Ajax应用程序中的联机/脱机状态的重要性,我预计其他浏览器供应商也会决定提供该属性。
在此之前,XHR或an Image()
或<img>
request都可以提供与所需功能接近的功能。
更新(2014/11/16)
现在,主要的浏览器都支持此属性,但是结果会有所不同。
引用Mozilla文档:
在Chrome和Safari中,如果浏览器无法连接到局域网(LAN)或路由器,则表明该浏览器处于脱机状态;其他所有条件都返回
true
。因此,尽管您可以假定浏览器在返回false
值时处于脱机状态,但不能假设真实值必然意味着浏览器可以访问互联网。您可能会得到误报,例如,当计算机运行的虚拟化软件具有始终“连接”的虚拟以太网适配器时。因此,如果您确实要确定浏览器的在线状态,则应开发其他检查方法。在Firefox和Internet Explorer中,将浏览器切换为脱机模式将发送一个
false
值。所有其他条件都返回一个true
值。
现在几乎所有主流浏览器都支持该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
事件),则可以保证没有Internet连接。
true
但是,如果是(或您收到online
事件),则仅表示系统最多已连接到某个网络。例如,这并不意味着您可以访问Internet。要进行检查,您仍然需要使用其他答案中描述的解决方案之一。
我最初打算将其发布为对格兰特·瓦格纳(Grant Wagner)的回答的更新,但似乎太过编辑,尤其是考虑到2014年的更新不是他的回答。
有很多方法可以做到这一点:
你可以把一个onerror
在img
像
<img src='http://www.example.com/singlepixel.gif'
onerror='alert("Connection dead");' />
如果源图像被移动/重命名,此方法也可能会失败,并且通常是ajax选项的次等选择。
因此,有几种不同的方法可以尝试检测这种情况,但并非完美无缺,但是在无法跳出浏览器沙箱并直接访问用户的网络连接状态的情况下,它们似乎是最佳选择。
if(navigator.onLine){
alert('online');
} else {
alert('offline');
}
您可以使用$ .ajax()的error
回调,如果请求失败,则触发该回调。如果textStatus
等于字符串“超时”,则可能意味着连接断开:
function (XMLHttpRequest, textStatus, errorThrown) {
// typically only one of textStatus or errorThrown
// will have info
this; // the options for this ajax request
}
从文档:
错误:如果请求失败,将调用一个函数。向该函数传递三个参数:XMLHttpRequest对象,描述发生的错误类型的字符串和可选的异常对象(如果发生)。第二个参数(除null外)的可能值为“超时”,“错误”,“未修改”和“ 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();
}
});
}
window.navigator.onLine
是您要查找的内容,但要添加的内容很少,首先,如果您要继续检查应用程序中的某些内容(例如查看用户是否突然脱机,这种情况在大多数情况下可以纠正),那么您还需要侦听更改),为此,您可以向窗口添加事件侦听器以检测任何更改,要检查用户是否离线,可以执行以下操作:
window.addEventListener("offline",
()=> console.log("No Internet")
);
并检查是否在线:
window.addEventListener("online",
()=> console.log("Connected Internet")
);
onLine
。浏览器对在线状态的定义大不相同。看一下developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine。
我认为这是一种非常简单的方法。
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;
if the browser is not able to connect to a local area network (LAN) or a router, it is offline; all other conditions return true
我一直在寻找一种客户端解决方案,以检测互联网是否关闭或服务器是否关闭。我发现的其他解决方案似乎总是依赖于第三方脚本文件或图像,在我看来,这似乎经不起时间的考验。外部托管脚本或图像将来可能会更改,并导致检测代码失败。
我找到了一种通过查找带有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)
}
}
});
我的方式。
<!-- 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>
某些方法的问题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 :(');
}
}
}
对于两个不同的senario,有2个答案:-
如果您在网站(即任何前端部分)上使用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>
但是,如果您在服务器端(即节点等)上使用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");
}
});
}
});