如何检测在线/离线事件跨浏览器?
我正在尝试使用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调用超时。
浏览器厂商无法就如何定义脱机达成一致。 某些浏览器具有“脱机工作”function,他们认为这是与缺lessnetworking访问权限相分离的,这一点与互联网访问不同。 整个事情是一团糟。 有些浏览器供应商在实际的networking访问丢失时更新navigator.onLine标志,其他浏览器则不会。
从规格:
如果用户代理肯定是脱机的(从networking断开连接),则返回false。 如果用户代理可能在线,则返回true。
当这个属性的值改变时,在线和离线的事件被触发。
如果当用户跟随链接或脚本请求远程页面(或者知道这样的尝试将失败)时用户代理不会联系networking,则navigator.onLine属性必须返回false,否则必须返回true。
最后,规格说明:
这个属性本质上是不可靠的。 计算机可以连接到networking,而无需访问Internet。
各大浏览器厂商在“离线”的含义上有所不同。
Chrome和Safari会自动检测你何时离线 – 这意味着当您拔下网线时,“在线”事件和属性将自动激活。
Firefox(Mozilla),Opera和IE采取了不同的方法,除非您明确地在浏览器中select“离线模式” – 即使您没有可用的networking连接,也认为您是“在线”。
Firefox / Mozilla的行为有一些有效的参数,在这个错误报告的评论中列出:
https://bugzilla.mozilla.org/show_bug.cgi?id=654579
但是,要回答这个问题 – 您不能依赖在线/离线事件/属性来检测是否存在实际的networking连接。
相反,您必须使用替代方法。
本Mozilla开发人员文章的“注释”部分提供了两个备用方法的链接:
https://developer.mozilla.org/en/Online_and_offline_events
“如果API没有在浏览器中实现,则可以使用其他信号来检测是否脱机,包括侦听来自XMLHttpRequest的AppCache错误事件和响应”
这链接到“侦听AppCache错误事件”方法的示例:
http://www.html5rocks.com/en/mobile/workingoffthegrid/#toc-appcache
…以及“侦听XMLHttpRequest失败”方法的示例:
http://www.html5rocks.com/en/mobile/workingoffthegrid/#toc-xml-http-request
HTH, – 乍得
今天有一个开源的JavaScript库可以完成这项工作:它被称为Offline.js
。
自动向用户显示在线/离线指示。
https://github.com/HubSpot/offline
一定要检查完整的自述文件 。 它包含您可以挂钩的事件。
这是一个testing页面 。 这很漂亮/有一个很好的反馈UI! 🙂
Offline.js模拟用户界面是一个Offline.js插件,允许您testing您的页面如何响应不同的连接状态,而无需使用暴力方法来禁用您的实际连接。
现在在所有主要浏览器上运行的最佳方式是以下脚本:
(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
window.navigator.onLine
属性及其相关事件在某些浏览器( 特别是Firefox桌面 )上是不可靠的,就像@Junto所说的那样,所以我写了一个小函数(使用jQuery)定期检查networking连接状态,并提出相应的offline
和online
活动:
// 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'); } });
navigator.online是一团糟
我试图做一个Ajax调用服务器时,我面对这一点。
客户端处于脱机状态时有几种可能的情况:
- ajax调用timouts并且您收到错误
- ajax调用返回成功,但味精为空
- ajax调用不会被执行,因为浏览器决定如此(可能是在navigator.onLine在一段时间后变成false)
我使用的解决scheme是用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); } }); }
在HTML5中,您可以使用navigator.onLine
属性。 看这里:
http://www.w3.org/TR/offline-webapps/#related
可能你当前的行为是随机的,因为JavaScript只准备好了“浏览器”variables,然后知道你是否离线和在线,但实际上并不检查networking连接。
让我们知道这是你在找什么。
亲切的问候,
从最近开始, navigator.onLine
在所有主stream浏览器上都显示相同,因此是可用的。
if (navigator.onLine) { // do things that need connection } else { // do things that don't need connection }
以正确的方式支持这个最老的版本是: Firefox 41 ,IE 9,Chrome 14和Safari 5。
目前,这将代表几乎所有的用户,但您应该始终检查您的页面的用户具有哪些function。
在FF 41之前,如果用户手动将浏览器置于离线模式,它将只显示false
。 在IE 8中,财产是在body
,而不是window
。
来源: caniuse
请find我为Offline编写的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检测客户端何时离线的代码示例。;
我使用HTML5caching清单中的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.txt的内容。 根据文件中的文本,您可以检测网页是否处于脱机状态。
您可以轻松地像下面一样检测离线的跨浏览器方式
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
replaceyoururl.com。
解决scheme的症结在于,如果您无法连接,请尝试连接到您的域名。 作品跨浏览器。
这是我的解决scheme。
经过IE,Opera,Chrome,FireFox,Safari,在IOS 8上使用Phonegap WebApp,在Android 4.4.2上使用Phonegap WebApp进行testing
这个解决scheme不适用于本地主机上的FireFox。
================================================== ===============================
onlineCheck.js(文件path:“root / js / onlineCheck.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 = "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(文件path:“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>
================================================== ===============================
checkOnline.php(文件path:“root”):
<?php echo 'true'; ?>
那么你可以尝试一下javascript插件,它可以实时监控浏览器的连接,并通知用户互联网或浏览器与互联网的连接是否中断。
Wiremonkey Javascript插件和演示,你可以在这里find
使用文件正文:
<body ononline="onlineConditions()" onoffline="offlineConditions()">(...)</body>
使用Javascript事件:
window.addEventListener('load', function() { function updateOnlineStatus(event) { var condition = navigator.onLine ? "online" : "offline"; if( condition == 'online' ){ console.log( 'condition: online') }else{ console.log( 'condition: offline') } } window.addEventListener('online', updateOnlineStatus(event) ); window.addEventListener('offline', updateOnlineStatus(event) ); });
参考 :
文档正文 : ononline事件
Javascript事件: 在线和离线事件
其他想法:
运送“networking连接与互联网连接不一样”上述方法的问题:您可以在应用程序启动时使用ajax检查一次互联网连接,并configuration在线/离线模式。 为用户创build一个重新连接button以联机。 并添加每个失败的ajax请求一个function,将用户踢回离线模式。