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


当前回答

我的方式。

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

其他回答

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

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;

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

Window.navigator.onLine

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

这个选项涉及到“window.navigator”的使用。这是浏览器导航界面下的一个属性,在大多数现代浏览器上可用。它真的不是一个可行的选择,因为首先它是以浏览器为中心的,其次大多数浏览器实现这个属性的方式不同。

In Firefox: The property returns a boolean value, with true meaning online and false meaning offline but the caveat here is that "the value is only updated when the user follows links or when a script requests a remote page." Hence if the user goes offline and you query the property from a js function or script, the property will always return true until the user follows a link. 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".

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

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

This involves making HTTP request to your own server resource and if reachable assume internet availability else the user is offline. There are some few caveats to this option.

没有服务器可用性是100%依赖的,因此如果由于某种原因您的服务器不可达,它会错误地假设用户离线,而他们连接到互联网。 对同一资源的多个请求可以返回缓存的响应,这使得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);
  });

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

We all know CORS is a thing.

该选项包括向外部服务器资源发出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,因为响应非常轻,它不经常更新)。 如果没有连接到资源,当你需要通知用户时,简单地说“连接错误”或“连接丢失”,而不是假设一个宽泛的“没有互联网连接”,这取决于许多因素。

您可以使用$.ajax()的错误回调,它在请求失败时触发。如果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!');
       }
   }
 });

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

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

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

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

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