如何检测跨浏览器的在线/离线事件?

问题描述 投票:102回答:14

我正在尝试使用HTML5在线和离线事件准确地检测浏览器何时脱机。

这是我的代码:

<script>
    // FIREFOX
    $(window).bind("online", applicationBackOnline); 
    $(window).bind("offline", applicationOffline);

    //IE
    window.onload = function() {
        document.body.ononline = IeConnectionEvent;
        document.body.onoffline = IeConnectionEvent;
    } 
</script>

当我在Firefox或IE上点击“脱机工作”时,它工作正常,但是当我实际拔掉电线时它会随机工作。

检测此变化的最佳方法是什么?我想避免重复带有超时的ajax调用。

javascript jquery javascript-events offline network-connection
14个回答
66
投票

浏览器供应商无法就如何定义离线达成一致。有些浏览器具有脱机工作功能,他们认为这与缺乏网络访问是分开的,这与互联网访问不同。整件事情一团糟。某些浏览器供应商在实际网络访问丢失时更新navigator.onLine标志,而其他浏览器供应商则不会。

从规格:

如果用户代理明确脱机(与网络断开连接),则返回false。如果用户代理可能在线,则返回true。

当此属性的值更改时,将触发联机和脱机事件。

如果用户代理在用户关注链接时或者脚本请求远程页面时(或者知道此类尝试将失败),则navigator.onLine属性必须返回false,否则必须返回true。

最后,规格说明:

该属性本质上是不可靠的。计算机可以连接到网络而无需访问Internet。


2
投票

您可以像下面一样轻松地检测离线跨浏览器方式

var randomValue = Math.floor((1 + Math.random()) * 0x10000)

$.ajax({
      type: "HEAD",
      url: "http://yoururl.com?rand=" + randomValue,
      contentType: "application/json",
      error: function(response) { return response.status == 0; },
      success: function() { return true; }
   });

你可以用document.location.pathname替换yoururl.com。

解决方案的关键是,尝试连接到您的域名,如果您无法连接 - 您处于离线状态。跨浏览器工作。


2
投票

我使用HTML5缓存清单中的FALLBACK选项来检查我的html5应用是在线还是离线:

FALLBACK:
/online.txt /offline.txt

在html页面中,我使用javascript tot读取在线/离线txt文件的内容:

<script>$.get( "urlto/online.txt", function( data ) {
$( ".result" ).html( data );
alert( data );
});</script>

脱机时,脚本将读取offline.text的内容。根据文件中的文本,您可以检测网页是否处于脱机状态。


0
投票

这是我的解决方案。

使用IE,Opera,Chrome,FireFox,Safari,IOS 8上的Phonegap WebApp和Android 4.4.2上的Phonegap WebApp进行测试

此解决方案不适用于localhost上的FireFox。

=================================================================================

在线Check.js(文件路径:“root / js / online Check.js):

var isApp = false;

function onLoad() {
        document.addEventListener("deviceready", onDeviceReady, false);
}

function onDeviceReady() {
    isApp = true;
    }


function isOnlineTest() {
    alert(checkOnline());
}

function isBrowserOnline(no,yes){
    //Didnt work local
    //Need "firefox.php" in root dictionary
    var xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHttp');
    xhr.onload = function(){
        if(yes instanceof Function){
            yes();
        }
    }
    xhr.onerror = function(){
        if(no instanceof Function){
            no();
        }
    }
    xhr.open("GET","checkOnline.php",true);
    xhr.send();
}

function checkOnline(){

    if(isApp)
    {
        var xhr = new XMLHttpRequest();
        var file = "http://dexheimer.cc/apps/kartei/neu/dot.png";

        try {
            xhr.open('HEAD', file , false); 
            xhr.send(null);

            if (xhr.status >= 200 && xhr.status < 304) {
                return true;
            } else {
                return false;
            }
        } catch (e) 
        {
            return false;
        }
    }else
    {
        var tmpIsOnline = false;

        tmpIsOnline = navigator.onLine;

        if(tmpIsOnline || tmpIsOnline == "undefined")
        {
            try{
                //Didnt work local
                //Need "firefox.php" in root dictionary
                var xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHttp');
                xhr.onload = function(){
                    tmpIsOnline = true;
                }
                xhr.onerror = function(){
                    tmpIsOnline = false;
                }
                xhr.open("GET","checkOnline.php",false);
                xhr.send();
            }catch (e){
                tmpIsOnline = false;
            }
        }
        return tmpIsOnline;

    }
}

=================================================================================

index.html(filepath:“root / index.html”):

<!DOCTYPE html>
<html>


<head>
    ...

    <script type="text/javascript" src="js/onlineCheck.js" ></script>

    ...

</head>

...

<body onload="onLoad()">

...

    <div onclick="isOnlineTest()">  
        Online?
    </div>
...
</body>

</html>

=================================================================================

检查Online.php(文件路径:“root”):

<?php echo 'true'; ?> 

0
投票

好吧,您可以尝试javascript插件,它可以实时监控浏览器连接,并通知用户互联网或浏览器与互联网连接是否已关闭。

Wiremonkey Javascript plugin和你可以在这里找到的演示

http://ryvan-js.github.io/


0
投票

使用文档正文:

<body ononline="onlineConditions()" onoffline="offlineConditions()">(...)</body>

使用Javascript事件:

window.addEventListener('load', function() {

  function updateOnlineStatus() {

    var condition = navigator.onLine ? "online" : "offline";
    if( condition == 'online' ){
        console.log( 'condition: online')
    }else{
        console.log( 'condition: offline')
    }

  }

  window.addEventListener('online',  updateOnlineStatus );
  window.addEventListener('offline', updateOnlineStatus );

});

参考: 文件 - 身体:ononline Event Javascript-Event:Online and offline events

其他想法: 运输“网络连接与互联网连接不同”上述方法存在问题:您可以在应用程序启动时使用ajax检查互联网连接一次,并配置在线/离线模式。创建一个重新连接按钮,供用户上线。并在每个失败的ajax请求上添加一个使用户重新进入离线模式的功能。


31
投票

主要的浏览器供应商在“离线”意味着什么不同。

Chrome和Safari会自动检测您何时“离线” - 这意味着当您拔下网络电缆时,“在线”事件和属性会自动触发。

Firefox(Mozilla),Opera和IE采用不同的方法,并认为您“在线”,除非您在浏览器中明确选择“离线模式” - 即使您没有可用的网络连接。

有关Firefox / Mozilla行为的有效参数,这些参数在此错误报告的注释中列出:

https://bugzilla.mozilla.org/show_bug.cgi?id=654579

但是,要回答这个问题 - 您不能依赖在线/离线事件/属性来检测是否存在网络连接。

相反,您必须使用其他方法。

此Mozilla Developer文章的“Notes”部分提供了两种替代方法的链接:

https://developer.mozilla.org/en/Online_and_offline_events

“如果API未在浏览器中实现,您可以使用其他信号来检测您是否处于脱机状态,包括侦听AppCache错误事件和XMLHttpRequest响应”

这链接到“侦听AppCache错误事件”方法的示例:

http://www.html5rocks.com/en/mobile/workingoffthegrid/#toc-appcache

...以及“侦听XMLHttpRequest失败”方法的示例:

http://www.html5rocks.com/en/mobile/workingoffthegrid/#toc-xml-http-request

HTH, - 乍得


18
投票

今天有一个开源JavaScript库可以完成这项工作:它叫做Offline.js

自动向用户显示在线/离线指示。

https://github.com/HubSpot/offline

一定要检查完整的README。它包含您可以挂钩的事件。

这是一个test page。这很漂亮/顺便说一下有很好的反馈用户界面! :)

Offline.js Simulate UI是一个Offline.js插件,允许您测试页面如何响应不同的连接状态,而无需使用强力方法来禁用实际连接。


15
投票

现在适用于所有主要浏览器的最佳方法是以下脚本:

(function () {
    var displayOnlineStatus = document.getElementById("online-status"),
        isOnline = function () {
            displayOnlineStatus.innerHTML = "Online";
            displayOnlineStatus.className = "online";
        },
        isOffline = function () {
            displayOnlineStatus.innerHTML = "Offline";
            displayOnlineStatus.className = "offline";
        };

    if (window.addEventListener) {
        /*
            Works well in Firefox and Opera with the 
            Work Offline option in the File menu.
            Pulling the ethernet cable doesn't seem to trigger it.
            Later Google Chrome and Safari seem to trigger it well
        */
        window.addEventListener("online", isOnline, false);
        window.addEventListener("offline", isOffline, false);
    }
    else {
        /*
            Works in IE with the Work Offline option in the 
            File menu and pulling the ethernet cable
        */
        document.body.ononline = isOnline;
        document.body.onoffline = isOffline;
    }
})();

资料来源:http://robertnyman.com/html5/offline/online-offline-events.html


11
投票

window.navigator.onLine属性及其相关事件目前在某些Web浏览器(especially Firefox desktop)上不可靠,正如@Junto所说,所以我写了一个小函数(使用jQuery)定期检查网络连接状态并引发适当的offlineonline事件:

// Global variable somewhere in your app to replicate the 
// window.navigator.onLine variable (it is not modifiable). It prevents
// the offline and online events to be triggered if the network
// connectivity is not changed
var IS_ONLINE = true;

function checkNetwork() {
  $.ajax({
    // Empty file in the root of your public vhost
    url: '/networkcheck.txt',
    // We don't need to fetch the content (I think this can lower
    // the server's resources needed to send the HTTP response a bit)
    type: 'HEAD',
    cache: false, // Needed for HEAD HTTP requests
    timeout: 2000, // 2 seconds
    success: function() {
      if (!IS_ONLINE) { // If we were offline
        IS_ONLINE = true; // We are now online
        $(window).trigger('online'); // Raise the online event
      }
    },
    error: function(jqXHR) {
      if (jqXHR.status == 0 && IS_ONLINE) {
        // We were online and there is no more network connection
        IS_ONLINE = false; // We are now offline
        $(window).trigger('offline'); // Raise the offline event
      } else if (jqXHR.status != 0 && !IS_ONLINE) {
        // All other errors (404, 500, etc) means that the server responded,
        // which means that there are network connectivity
        IS_ONLINE = true; // We are now online
        $(window).trigger('online'); // Raise the online event
      }
    }
  });
}

你可以像这样使用它:

// Hack to use the checkNetwork() function only on Firefox 
// (http://stackoverflow.com/questions/5698810/detect-firefox-browser-with-jquery/9238538#9238538)
// (But it may be too restrictive regarding other browser
// who does not properly support online / offline events)
if (!(window.mozInnerScreenX == null)) {
    window.setInterval(checkNetwork, 30000); // Check the network every 30 seconds
}

要收听离线和在线活动(借助jQuery):

$(window).bind('online offline', function(e) {
  if (!IS_ONLINE || !window.navigator.onLine) {
    alert('We have a situation here');
  } else {
    alert('Battlestation connected');
  }
});

10
投票

从最近开始,navigator.onLine在所有主流浏览器上显示相同,因此是可用的。

if (navigator.onLine) {
  // do things that need connection
} else {
  // do things that don't need connection
}

以正确方式支持此功能的最古老版本包括:Firefox 41,IE 9,Chrome 14和Safari 5。

目前,这几乎代表了所有用户,但您应该始终检查页面用户的功能。

在FF 41之前,如果用户手动将浏览器置于离线模式,它将仅显示false。在IE 8中,该属性位于body,而不是window

来源:caniuse


6
投票

navigator.onLine是一团糟

我在尝试对服务器进行ajax调用时遇到此问题。

客户端脱机时有几种可能的情况:

  • ajax调用时钟,你收到错误
  • ajax调用返回成功,但msg为null
  • ajax调用没有被执行,因为浏览器决定这样(可能是这时navigator.onLine在一段时间后变为false)

我使用的解决方案是使用javascript控制自己的状态。我设置了成功呼叫的条件,在任何其他情况下我假设客户端处于脱机状态。像这样的东西:

var offline;
pendingItems.push(item);//add another item for processing
updatePendingInterval = setInterval("tryUpdatePending()",30000);
tryUpdatePending();

    function tryUpdatePending() {

        offline = setTimeout("$('#offline').show()", 10000);
        $.ajax({ data: JSON.stringify({ items: pendingItems }), url: "WebMethods.aspx/UpdatePendingItems", type: "POST", dataType: "json", contentType: "application/json; charset=utf-8",
          success: function (msg) {
            if ((!msg) || msg.d != "ok")
              return;
            pending = new Array(); //empty the pending array
            $('#offline').hide();
            clearTimeout(offline);
            clearInterval(updatePendingInterval);
          }
        });
      }

5
投票

在HTML5中,您可以使用navigator.onLine属性。看这里:

http://www.w3.org/TR/offline-webapps/#related

可能你当前的行为是随机的,因为javascript只准备好“浏览器”变量然后知道你是否离线和在线,但它实际上并没有检查网络连接。

如果您正在寻找,请告诉我们。

亲切的问候,


2
投票

请找到我为脱机编写的require.js模块。

define(['offline'], function (Offline) {
    //Tested with Chrome and IE11 Latest Versions as of 20140412
    //Offline.js - http://github.hubspot.com/offline/ 
    //Offline.js is a library to automatically alert your users 
    //when they've lost internet connectivity, like Gmail.
    //It captures AJAX requests which were made while the connection 
    //was down, and remakes them when it's back up, so your app 
    //reacts perfectly.

    //It has a number of beautiful themes and requires no configuration.
    //Object that will be exposed to the outside world. (Revealing Module Pattern)

    var OfflineDetector = {};

    //Flag indicating current network status.
    var isOffline = false;

    //Configuration Options for Offline.js
    Offline.options = {
        checks: {
            xhr: {
                //By default Offline.js queries favicon.ico.
                //Change this to hit a service that simply returns a 204.
                url: 'favicon.ico'
            }
        },

        checkOnLoad: true,
        interceptRequests: true,
        reconnect: true,
        requests: true,
        game: false
    };

    //Offline.js raises the 'up' event when it is able to reach
    //the server indicating that connection is up.
    Offline.on('up', function () {
        isOffline = false;
    });

    //Offline.js raises the 'down' event when it is unable to reach
    //the server indicating that connection is down.
    Offline.on('down', function () {
        isOffline = true;
    });

    //Expose Offline.js instance for outside world!
    OfflineDetector.Offline = Offline;

    //OfflineDetector.isOffline() method returns the current status.
    OfflineDetector.isOffline = function () {
        return isOffline;
    };

    //start() method contains functionality to repeatedly
    //invoke check() method of Offline.js.
    //This repeated call helps in detecting the status.
    OfflineDetector.start = function () {
        var checkOfflineStatus = function () {
            Offline.check();
        };
        setInterval(checkOfflineStatus, 3000);
    };

    //Start OfflineDetector
    OfflineDetector.start();
    return OfflineDetector;
});

请阅读此博文,让我知道您的想法。 http://zen-and-art-of-programming.blogspot.com/2014/04/html-5-offline-application-development.html它包含使用offline.js检测客户端何时脱机的代码示例。

© www.soinside.com 2019 - 2024. All rights reserved.