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


当前回答

我不得不为一个与学校有很多合作的客户制作一个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仍然意味着您在线

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

只需使用导航器。如果这是真的,那么你是在线的,否则离线

我知道这个问题已经被回答了,但我想补充我的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,因为响应非常轻,它不经常更新)。 如果没有连接到资源,当你需要通知用户时,简单地说“连接错误”或“连接丢失”,而不是假设一个宽泛的“没有互联网连接”,这取决于许多因素。

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

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