webapp 有时候需要检测应用是否处于离线状态,以此做出一些针对性的展示。这里小结一下如何来检测离线。
navigator.onLine 属性结合 online/offline 事件
使用起来很简单,我们可以监听这两个事件,在事件回调里做任何想做的事情即可:
1 | window.ononline = function(e) { |
XHR 检测
思路是使用 XHR 请求一个肯定存在的资源,如果失败,很有可能表明用户网络出了故障,然后就可以做出一些提示。
1 | var xhr = new XMLHttpRequest(); |
判断响应码
xhr
的status
属性在初始时为 0,若请求未完成时这个属性仍然是 0,参见MDN 恰好断网的情况下请求不会完成,其他情况下都会有专门的响应码,所以我们可以根据status
属性来判断:
1 | var xhr = new XMLHttpRequest(); |
利用 fetch api
fetch
与ajax
有一个很大的不同:不会因为普通的后台错误码而导致请求失败,只会把response.ok
设为 false,fetch 只会因为网络问题或者其他阻塞请求完成的原因而 reject。
所以如果是利用fecth
进行的资源请求,那么其失败时就可以提示用户的网络有问题,例如:
1 | fetch('../icons.png') |
借助 serviceworker 的 sync 事件
参考了 2 篇文章:
先注册一个 Sync 事件,然后在 serviceworker 中监听这个事件,事件监听器会在用户有网络时被调用。如果用户在断网情况下触发了 sync 事件,监听函数会在有网络时立即调用。
例如我们想在用户访问我们的网站时给他们发送一个通知:
在页面加载时触发 sync 事件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20new Promise(function(resolve, reject) {
Notification.requestPermission(function(result) {
if (result !== 'granted') {
return reject(Error('Denied notification permission'));
}
resolve();
});
})
.then(function() {
return navigator.serviceWorker.ready;
})
.then(function(reg) {
return reg.sync.register('syncTest'); // 触发sync事件
})
.then(function() {
console.log('SUCCESS Sync registered');
})
.catch(function(err) {
console.log('FAILED Sync registe', err);
});在 serviceworker 中监听事件
1
2
3self.addEventListener('sync', function(event) {
self.registration.showNotification('你好啊!');
});