我如何在JavaScript中检测互联网连接是否离线?
我如何在JavaScript中检测互联网连接是否离线?
我知道这个问题已经有了答案,但我想补充我的看法,说明什么更好,什么不好。
我注意到有些答案提到了这个选项,但他们从未提到任何相关的注意事项。
这个选项涉及使用“window.navigator.onLine”,这是现代大多数浏览器中可用的浏览器导航器接口下的一个属性。它真的不是检查互联网可用性的可行选项,因为首先,它是以浏览器为中心
,其次,大多数浏览器以不同的方式实现此属性
。
在Firefox中: 该属性返回一个布尔值,其中
true
表示联机,false
表示脱机,但是这里的注意事项是, “只有当用户跟随链接或脚本请求远程页面时,才会更新该值。
” 因此,如果用户处于离线状态并且您从js函数或脚本查询属性,则该属性将始终返回true
,直到用户跟随链接。在Chrome和Safari中: 如果浏览器无法连接到本地区域网络(LAN)或路由器,则它处于脱机状态,所有其他情况都返回true。因此,尽管您可以假设浏览器处于脱机状态时它会返回false值,但您不能假设true值必然意味着浏览器可以访问互联网。您可能会收到错误的阳性,例如在计算机运行虚拟化软件且始终“连接”的虚拟以太网适配器的情况下。
以上声明只是想让您知道仅凭浏览器是不够的。因此,基本上这个选项是不可靠的。
如果您同意您的服务器始终在线,那么您可以选择此选项。
以下是一个获取自己资源的简单片段:
// 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);
});
这个选项涉及向外部服务器资源发出HTTP请求,如果能够访问则假定已连接到互联网,否则用户处于离线状态。这种方法的主要限制是跨源资源共享(CORS),它会限制访问。大多数信誉良好的网站都会阻止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中得出结论。
请记住,您的用户也可能处于一些禁止访问某些网站或资源的环境中,这将影响连接性检查的逻辑。最好的方法是:
我需要为一个经常与学校打交道的客户制作一个基于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();
}
});
}
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;
像 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 :(');
}
}
}
$.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)
}
}
});
fetch('https://google.com', {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
mode: 'no-cors',
}).then((result) => {
console.log(result)
}).catch(e => {
console.error(e)
})
设置no-cors的原因是即使在我的电脑上禁用了网络连接,我仍然收到cors错误。所以无论是否有互联网连接,都会收到CORS阻止的消息。添加no-cors可以使请求不透明,这显然似乎可以绕过CORS并允许我简单地检查是否可以连接到Google。
提示:我在此处使用fetch进行http请求。 https://www.npmjs.com/package/fetch
我的方式。
<!-- 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>
如果 navigator.onLine
为 true
,那么你处于在线状态,否则处于离线状态。
window.navigator.onLine
,这个函数可以正常工作。你需要监听 online
/offline
事件来查看变化。请参考以下链接:https://medium.com/@JackPu/how-javascript-detect-the-network-status-42f3a6d85f96 或 https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine。 - phoenisx您可以尝试这个,如果网络已连接,它将返回true。
function isInternetConnected(){return navigator.onLine;}
请求错误中的请求头
$.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");
}
});
}
});