Javascript 如何跨浏览器检测在线/离线事件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3181080/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to detect online/offline event cross-browser?
提问by Pierre Duplouy
I'm trying to accurately detect when the browser goes offline, using the HTML5 online and offline events.
我正在尝试使用 HTML5 在线和离线事件准确检测浏览器何时离线。
Here's my code:
这是我的代码:
<script>
// FIREFOX
$(window).bind("online", applicationBackOnline);
$(window).bind("offline", applicationOffline);
//IE
window.onload = function() {
document.body.ononline = IeConnectionEvent;
document.body.onoffline = IeConnectionEvent;
}
</script>
It works fine when I just hit "Work offline" on either Firefox or IE, but it's kind of randomly working when I actually unplug the wire.
当我在 Firefox 或 IE 上点击“离线工作”时它工作正常,但是当我真正拔掉电线时它会随机工作。
What's the best way to detect this change? I'd like to avoid repeating ajax calls with timeouts.
检测这种变化的最佳方法是什么?我想避免重复超时的 ajax 调用。
采纳答案by Rebecca
The browser vendors cannot agree on how to define offline. Some browsers have a Work Offline feature, which they consider separate to a lack of network access, which again is different to internet access. The whole thing is a mess. Some browser vendors update the navigator.onLine flag when actual network access is lost, others don't.
浏览器供应商无法就如何定义离线达成一致。一些浏览器具有离线工作功能,他们认为这与缺乏网络访问是分开的,这又与互联网访问不同。整件事都是一团糟。当实际网络访问丢失时,一些浏览器供应商会更新 navigator.onLine 标志,而另一些则不会。
From the spec:
从规范:
Returns false if the user agent is definitely offline (disconnected from the network). Returns true if the user agent might be online.
The events online and offline are fired when the value of this attribute changes.
The navigator.onLine attribute must return false if the user agent will not contact the network when the user follows links or when a script requests a remote page (or knows that such an attempt would fail), and must return true otherwise.
如果用户代理肯定离线(与网络断开连接),则返回 false。如果用户代理可能在线,则返回 true。
当该属性的值发生变化时,将触发 online 和 offline 事件。
如果当用户点击链接或脚本请求远程页面(或知道这样的尝试会失败)时用户代理不会联系网络,则 navigator.onLine 属性必须返回 false,否则必须返回 true。
Finally, the spec notes:
最后,规范指出:
This attribute is inherently unreliable. A computer can be connected to a network without having Internet access.
这个属性本质上是不可靠的。计算机可以连接到网络而无需访问 Internet。
回答by thewoolleyman
The major browser vendors differ on what "offline" means.
主要的浏览器供应商对“离线”的含义有所不同。
Chrome and Safari will detect when you go "offline" automatically - meaning that "online" events and properties will fire automatically when you unplug your network cable.
Chrome 和 Safari 会自动检测您何时“离线”——这意味着当您拔下网线时,“在线”事件和属性将自动触发。
Firefox (Mozilla), Opera, and IE take a different approach, and consider you "online" unless you explicitly pick "Offline Mode" in the browser - even if you don't have a working network connection.
Firefox (Mozilla)、Opera 和 IE 采取不同的方法,并认为您“在线”,除非您在浏览器中明确选择“离线模式”——即使您没有有效的网络连接。
There are valid arguments for the Firefox/Mozilla behavior, which are outlined in the comments of this bug report:
Firefox/Mozilla 的行为有一些有效的论据,在此错误报告的评论中进行了概述:
https://bugzilla.mozilla.org/show_bug.cgi?id=654579
https://bugzilla.mozilla.org/show_bug.cgi?id=654579
But, to answer the question - you can't rely on the online/offline events/property to detect if there is actually network connectivity.
但是,要回答这个问题 - 您不能依靠在线/离线事件/属性来检测是否确实存在网络连接。
Instead, you must use alternate approaches.
相反,您必须使用替代方法。
The "Notes" section of this Mozilla Developer article provides links to two alternate methods:
这篇 Mozilla 开发人员文章的“注释”部分提供了两种替代方法的链接:
https://developer.mozilla.org/en/Online_and_offline_events
https://developer.mozilla.org/en/Online_and_offline_events
"If the API isn't implemented in the browser, you can use other signals to detect if you are offline including listening for AppCache error events and responses from XMLHttpRequest"
“如果该 API 未在浏览器中实现,您可以使用其他信号来检测您是否处于离线状态,包括侦听 AppCache 错误事件和来自 XMLHttpRequest 的响应”
This links to an example of the "listening for AppCache error events" approach:
这链接到“侦听 AppCache 错误事件”方法的示例:
http://www.html5rocks.com/en/mobile/workingoffthegrid/#toc-appcache
http://www.html5rocks.com/en/mobile/workingoffthegrid/#toc-appcache
...and an example of the "listening for XMLHttpRequest failures" approach:
...以及“侦听 XMLHttpRequest 失败”方法的示例:
http://www.html5rocks.com/en/mobile/workingoffthegrid/#toc-xml-http-request
http://www.html5rocks.com/en/mobile/workingoffthegrid/#toc-xml-http-request
HTH, -- Chad
HTH, -- 乍得
回答by Leniel Maccaferri
Today there's an open source JavaScript library that does this job: it's called Offline.js.
今天有一个开源 JavaScript 库可以完成这项工作:它被称为Offline.js.
Automatically display online/offline indication to your users.
自动向用户显示在线/离线指示。
https://github.com/HubSpot/offline
https://github.com/HubSpot/offline
Be sure to check the full README. It contains events that you can hook into.
请务必查看完整的README。它包含您可以挂钩的事件。
Here's a test page. It's beautiful/has a nice feedback UI by the way! :)
这是一个测试页面。顺便说一下,它很漂亮/有一个很好的反馈用户界面!:)
Offline.js Simulate UI is an Offline.js plug-in that allows you to test how your pages respond to different connectivity states without having to use brute-force methods to disable your actual connectivity.
Offline.js Simulate UI 是一个 Offline.js 插件,它允许您测试页面如何响应不同的连接状态,而不必使用暴力方法来禁用您的实际连接。
回答by tmaximini
The best way which works now on all Major Browsers is the following Script:
现在适用于所有主要浏览器的最佳方式是以下脚本:
(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;
}
})();
Source: http://robertnyman.com/html5/offline/online-offline-events.html
来源:http: //robertnyman.com/html5/offline/online-offline-events.html
回答by Haroen Viaene
Since recently, navigator.onLineshows the same on all major browsers, and is thus useable.
最近,navigator.onLine在所有主要浏览器上显示相同,因此可用。
if (navigator.onLine) {
// do things that need connection
} else {
// do things that don't need connection
}
The oldest versions that support this in the right way are: Firefox 41, IE 9, Chrome 14 and Safari 5.
以正确方式支持此功能的最旧版本是:Firefox 41、IE 9、Chrome 14 和 Safari 5。
Currently this will represent almost the whole spectrum of users, but you should always check what the users of your page have of capabilities.
目前,这将代表几乎所有用户,但您应该始终检查您页面的用户具有哪些功能。
Previous to FF 41, it would only show falseif the user put the browser manually in offline mode. In IE 8, the property was on the body, instead of window.
在 FF 41 之前,它只会显示false用户是否手动将浏览器置于离线模式。在 IE 8 中,该属性位于body, 而不是window。
source: caniuse
来源:caniuse
回答by Epoc
The window.navigator.onLineattribute and its associated events are currently unreliable on certain web browsers (especially Firefox desktop) as @Junto said, so I wrote a little function (using jQuery) that periodically check the network connectivity status and raise the appropriate offlineand onlineevent:
该window.navigator.onLine属性及其相关的事件都在某些Web浏览器(目前不可靠尤其是Firefox的桌面)作为@Junto说,所以我写了(使用jQuery)能够定期检查网络连接状态,并提高相应的一个小功能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
}
}
});
}
You can use it like this:
你可以这样使用它:
// 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
}
To listen to the offline and online events (with the help of jQuery):
收听离线和在线事件(在 jQuery 的帮助下):
$(window).bind('online offline', function(e) {
if (!IS_ONLINE || !window.navigator.onLine) {
alert('We have a situation here');
} else {
alert('Battlestation connected');
}
});
回答by Toolkit
navigator.onLine is a mess
navigator.onLine 一团糟
I face this when trying to make an ajax call to the server.
我在尝试对服务器进行 ajax 调用时遇到了这个问题。
There are several possible situations when the client is offline:
客户端离线有几种可能的情况:
- the ajax call timouts and you receive error
- the ajax call returns success, but the msg is null
- the ajax call is not executed because browser decides so (may be this is when navigator.onLine becomes false after a while)
- ajax 调用超时,您收到错误
- ajax 调用返回成功,但 msg 为空
- ajax 调用未执行,因为浏览器决定这样做(可能是在一段时间后 navigator.onLine 变为 false 时)
The solution I am using is to control the status myself with javascript. I set the condition of a successful call, in any other case I assume the client is offline. Something like this:
我使用的解决方案是使用 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);
}
});
}
回答by Trefex
In HTML5 you can use the navigator.onLineproperty. Look here:
在 HTML5 中,您可以使用该navigator.onLine属性。看这里:
http://www.w3.org/TR/offline-webapps/#related
http://www.w3.org/TR/offline-webapps/#related
Probably your current behavior is random as the javascript only ready the "browser" variable and then knows if you're offline and online, but it doesn't actually check the Network Connection.
可能您当前的行为是随机的,因为 javascript 只准备好“浏览器”变量,然后知道您是否处于离线和在线状态,但它实际上并没有检查网络连接。
Let us know if this is what you're looking for.
如果这就是您要找的,请告诉我们。
Kind Regards,
亲切的问候,
回答by Srihari Sridharan
Please find the require.js module that I wrote for 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;
});
Please read this blog post and let me know your thoughts. http://zen-and-art-of-programming.blogspot.com/2014/04/html-5-offline-application-development.htmlIt contains a code sample using offline.js to detect when the client is offline.
请阅读这篇博文,让我知道你的想法。http://zen-and-art-of-programming.blogspot.com/2014/04/html-5-offline-application-development.html包含一个使用offline.js检测客户端何时离线的代码示例。
回答by harishr
you can detect offline cross-browser way easily like below
您可以像下面一样轻松检测离线跨浏览器方式
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; }
});
you can replace yoururl.com by document.location.pathname.
您可以将 yoururl.com 替换为document.location.pathname。
The crux of the solution is, try to connect to your domain name, if you are not able to connect - you are offline. works cross browser.
解决方案的关键是,尝试连接到您的域名,如果您无法连接 - 您处于离线状态。跨浏览器工作。

