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


当前回答

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

我找到了一种方法,通过查找带有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)
        }
    }
});

其他回答

 if(navigator.onLine){
  alert('online');
 } else {
  alert('offline');
 }

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

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

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

更新(2014/11/16)

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

引用自Mozilla文档:

In Chrome and Safari, 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. So while you can assume that the browser is offline when it returns a false value, you cannot assume that a true value necessarily means that the browser can access the internet. You could be getting false positives, such as in cases where the computer is running a virtualization software that has virtual ethernet adapters that are always "connected." Therefore, if you really want to determine the online status of the browser, you should develop additional means for checking. In Firefox and Internet Explorer, switching the browser to offline mode sends a false value. All other conditions return a true value.

导航器等方法的问题。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 :(');
         }
     }
}

您可以通过发出失败的XHR请求来确定连接已丢失。

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

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

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

Sidenote: Sending a Ping could be achieved in the same way that you would make any kind of two-way ajax request, but sending a ping to google, in this case, would pose some challenges. First, we'd have the same cross-domain issues that are typically encountered in making Ajax communications. One option is to set up a server-side proxy, wherein we actually ping google (or whatever site), and return the results of the ping to the app. This is a catch-22 because if the internet connection is actually the problem, we won't be able to get to the server, and if the connection problem is only on our own domain, we won't be able to tell the difference. Other cross-domain techniques could be tried, for example, embedding an iframe in your page which points to google.com, and then polling the iframe for success/failure (examine the contents, etc). Embedding an image may not really tell us anything, because we need a useful response from the communication mechanism in order to draw a good conclusion about what's going on. So again, determining the state of the internet connection as a whole may be more trouble than it's worth. You'll have to weight these options out for your specific app.

我的方式。

<!-- 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>