检测到Internet连接离线?


Answers:


134

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

标准方法是重试几次请求。如果未通过,请警告用户检查连接,然后正常失败

旁注:将整个应用程序置于“脱机”状态可能会导致很多容易出错的状态处理工作。无线连接可能会来去去等。因此,最好的选择是妥善地失败,保留数据,并警告用户..允许他们最终解决连接问题(如果有的话),并在相当多的宽恕下继续使用您的应用。

旁注:您可以检查像google这样的可靠网站的连通性,但这可能并不完全有用,仅是尝试提出自己的请求,因为尽管Google可能可用,但您自己的应用程序可能不可用,并且您仍将继续必须处理您自己的连接问题。尝试向Google发送ping通知是确认互联网连接本身已关闭的好方法,因此,如果该信息对您有用,那么麻烦就值得了。

旁注发送Ping的方式可以与您发出任何双向双向Ajax请求的方式相同,但是在这种情况下,向Google发送Ping会带来一些挑战。首先,我们将遇到与进行Ajax通信时通常遇到的相同的跨域问题。一种选择是设置服务器端代理,我们实际上在其中ping搜索Google(或任何站点),并将ping结果返回给应用程序。这是一个陷阱22因为如果实际上是Internet连接,我们将无法连接到服务器,并且如果连接问题仅在我们自己的域上,我们将无法分辨出差异。可以尝试其他跨域技术,例如,在您的网页中嵌入一个指向google.com的iframe,然后轮询该iframe的成功/失败(检查内容等)。嵌入图像可能并不能真正告诉我们任何信息,因为我们需要通信机制提供有用的响应,以便对正在发生的事情得出良好的结论。因此,再次确定整个Internet连接的状态可能比其价值更大。您必须为您的特定应用权衡这些选项。


84
重复的“ Sidenote”听起来像Dwight Schrute所说的“ Question ...” :-)
Brian Kelly

19
为什么“ catch-22”以粗体显示?
09年

33
在2012年现在,您可以检查变量navigator.onLine;)
JoãoPintoJerónimo

13
出于同样的原因,navigator.online / offline也不可靠。见stackoverflow.com/questions/3181080/...
Efran Cobisi

17
您可能想查看Offline.js,这是为此目的而构建的开源库。
亚当

51

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值。


5
navigator.onLine是HTML5的一部分-其他浏览器已经具有提供此功能的开发版本-Firefox 3已在今天提供。
olliej

-但很遗憾,我们通常需要它在早期版本的IE中不可用。
keparo

22
navigator.onLine显示浏览器的状态,而不是实际的连接。因此,您可以将您的浏览器设置为“在线”,但实际上会因为连接断开而失败。仅当浏览器设置为脱机浏览时,navigator.onLine才为false。

5
如果我在Nexus7上关闭了WI-FI,则页面仍显示navigator.onLine为TRUE。糟糕...
2014年

40

现在几乎所有主流浏览器都支持该window.navigator.onLine属性以及相应的onlineoffline窗口事件:

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.onLinefalse(或您收到offline事件),则可以保证没有Internet连接。

true但是,如果是(或您收到online事件),则仅表示系统最多已连接到某个网络。例如,这并不意味着您可以访问Internet。要进行检查,您仍然需要使用其他答案中描述的解决方案之一。

我最初打算将其发布为对格兰特·瓦格纳(Grant Wagner)的回答的更新,但似乎太过编辑,尤其是考虑到2014年的更新不是他的回答


最佳答案。谢谢。
vibs2006 '19

我最近有机会在离线行为方面做了一些工作。这些事件很好用,但ios野生动物园会造成问题。当您打开手机的互联网时,离线/在线事件最多会延迟2秒,由于视觉渲染的原因,这可能会带来问题,因为您无法预测未来。我只是想提一提,可能会对某人有所帮助。
TeeJaay

38

有很多方法可以做到这一点:

  • AJAX请求到您自己的网站。如果该请求失败,则很有可能是连接故障。在JQuery的文件有一个部分处理失败的AJAX请求。执行此操作时请注意“ 相同来源策略”,这可能会阻止您访问域外的网站。
  • 你可以把一个onerrorimg

    <img src='http://www.example.com/singlepixel.gif' 
          onerror='alert("Connection dead");' />

    如果源图像被移动/重命名,此方法也可能会失败,并且通常是ajax选项的次等选择。

因此,有几种不同的方法可以尝试检测这种情况,但并非完美无缺,但是在无法跳出浏览器沙箱并直接访问用户的网络连接状态的情况下,它们似乎是最佳选择。


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

11
如果在浏览器上,它将始终返回TRUE。
Slavcho 2013年

2
好吧,首先我试图禁用仅局域网,但是它总是返回TRUE。因此,当我禁用所有网络(LAN2,Virtual Box等)时,它返回FALSE。
Slavcho 2013年

3
该答案重复了3年前的几个现有答案。
JasonMArcher 2014年

2
它不检查Internet连接,仅检查LAN连接
Suganth G 2016年

在HTML 5,JavaScript,macbook(使用wifi)中为我工作,甚至在移动设备中工作。但问题是-当每次打开wifi都返回TRUE时,即使我关闭wifi也是如此。
S.Yadav

11

HTML5应用程序缓存API指定了navigator.onLine,该浏览器目前在IE8 Beta,WebKit(例如Safari)每晚提供,并且在Firefox 3中已经受支持。


11

您可以使用$ .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!');
       }
   }
 });

9

正如olliej所说,使用navigator.onLine浏览器属性比发送网络请求更可取,因此,对于developer.mozilla.org/En/Online_and_offline_events,旧版本的Firefox和IE甚至都支持它。

最近,WHATWG已指定onlineoffline事件的添加,以防您需要对navigator.onLine更改做出反应。

还请注意Daniel Silveira发布的链接,该链接指出依靠那些信号/属性与服务器同步并不总是一个好主意。


更新:从2015年开始,它似乎可以在大多数浏览器中使用,请参见caniuse图表文章
Olga

7

我必须为与学校打交道的客户制作一个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();
        }
    });
}

7
window.navigator.onLine

是您要查找的内容,但要添加的内容很少,首先,如果您要继续检查应用程序中的某些内容(例如查看用户是否突然脱机,这种情况在大多数情况下可以纠正),那么您还需要侦听更改),为此,您可以向窗口添加事件侦听器以检测任何更改,要检查用户是否离线,可以执行以下操作:

window.addEventListener("offline", 
  ()=> console.log("No Internet")
);

并检查是否在线:

window.addEventListener("online", 
  ()=> console.log("Connected Internet")
);

2
您必须注意onLine。浏览器对在线状态的定义大不相同。看一下developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine
Andreas Baumgart

1
您的回答是错误的。“在线”属性与互联网的连通性无关。请参阅上面有关Web API的参考。
Alexandre V.

6

对您的域进行ajax调用是检测您是否离线的最简单方法

$.ajax({
      type: "HEAD",
      url: document.location.pathname + "?param=" + new Date(),
      error: function() { return false; },
      success: function() { return true; }
   });

这只是给您的概念,应该加以改进。

例如error = 404仍应表示您在线


4

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

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;

在线并不意味着有互联网连接。根据developer.mozilla.org/zh-CN/docs/Web/API/NavigatorOnLine/onLine的 说法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
Shmuel Kamensky

2

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

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

2
截至2016年5月10日,这不起作用,不知道为什么不希望浪费其他人的时间。
布伦

我认为这样不会对禁止的和错误的请求错误
起作用

1

我的方式。

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

1

某些方法的问题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 :(');
         }
     }
}

0

对于两个不同的senario,有2个答案:-

  1. 如果您在网站(即任何前端部分)上使用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>

  2. 但是,如果您在服务器端(即节点等)上使用js,则可以通过发出失败的XHR请求来确定连接丢失。

    标准方法是重试几次请求。如果没有通过,请警告用户检查连接,然后正常失败。


0

请求头中的请求错误

$.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"); 
              }
         });
    }   
});

-1

这是我所拥有的一个辅助工具的片段。这是命名空间的javascript:

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

您应该将此方法与方法检测一起使用,否则将触发执行此操作的“替代”方法。当这将是所有需要的时间快到了。其他方法是黑客。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.