7.1 解锁缓存
在没有网络时,用户尝试访问 Web 应用,Service Worker 能拦截 HTTP 请求,返回用户要查看的页面的缓存版本。
7.2 提供离线文件
↓ 将离线页面添加到 Service Worker 缓存中
const cacheName = 'offline-cache'
const offlineUrl = 'offline-page.html'
self.addEventListener('install', event => {
event.waitUntil(
caches.open(cacheName).then(function (cache) {
return cache.addAll([offlineUrl])
})
)
})
↓ 当用户没有连接时提供离线页面
self.addEventListener('fetch', event => {
if (event.request.method === 'GET' && event.request.headers.get('accept').includes('text/html')) {
event.respondWith(fetch(event.request.url).catch(error => {
return caches.match(offlineUrl)
}))
} else {
event.respondWith(fetch(event.request))
}
})
↓ 如果资源没有存储在缓存中,则降级成默认的离线页面
const cacheName = 'latestNews-v1'
const offlineUrl = 'offline-page.html'
self.addEventListener('install', event => {
event.waitUntil(
caches.open(cacheName)
.then(cache => cache.addAll([
'./js/main.js',
'./js/article.js',
'./images/newspaper.svg',
'./css/site.css',
'./data/latest.json',
'./data/data-1.json',
'./article.html',
'./index.html',
offlineUrl
]))
)
})
self.addEventListener('fetch', event => {
event.respondWith(caches.match(event.request).then(function (response) {
if (response) return response
var fetchRequest = event.request.clone()
return fetch(fetchRequest).then(function (response) {
if (!response || response.status !== 200) return response
var responseToCache = response.clone()
caches.open(cacheName).then(function (cache) {
cache.put(event.request, responseToCache)
})
return response
}).catch(error => { // 如果由于任何原因 fetch 事件失败,就检查用户是否跳转至其他页面并且请求的是 HTML 网页
if (event.request.method === 'GET' && event.request.headers.get('accept').includes('text/html')) {
return caches.match(offlineUrl) // 返回在 Service Worker 安装阶段存储在缓存中的离线页面
}
})
}))
})
上一段代码永远会先从缓存中寻找资源,如果缓存中找不到,才会转而去发起请求。如果它无法通过网络来获取下一个网页,又会降级成缓存的离线页面。
7.3 几个需要注意的问题
是否需要在 Service Worker 安装期间将整个网站缓存?
当提供离线功能时,请考虑用户需求及用户量。用户是如何访问你的网站的?他们是否需要一次下载完整个网站,或者当它们访问某个新页面时再去获取?
7.4 缓存是非永久性的
每个站点都具有一定量的可用空间,这些空间可以与其他所有基于 Web 的存储器(LocalStorage、IndexedDB 和设备上的文件系统)共享。
7.5 离线用户体验
var offlineNotification = document.getElementById('offline')
function showIndicator() { // 当用户离线时,此函数用来显示离线通知
offlineNotification.innerHTML = 'You are currently offline.'
offlineNotification.className = 'showOfflineNotification'
}
function hideIndicator() { // 当用户再次上线时,此函数用来隐藏离线通知
offlineNotification.className = 'hideOfflineNotification'
}
window.addEventListener('online', hideIndicator)
window.addEventListener('offline', showIndicator)
7.6 跟踪离线使用情况
如果用户处于离线状态,则无法使用传统的 Web 分析方法来跟踪它们。在没有网络连接的情况下,分析请求将无法发出,用户的操作行为将会丢失。
Google 的开源工具库 Workbox 提供了一个叫 googleAnalytics 的离线分析工具。当用户离线时,这个库会将所有分析请求放入队列中等候,一旦用户重新连接网络,会将队列中的请求发送到分析服务器。



![[译] 终于,JavaScript 有了安全的数组方法](https://img-1252058122.cos.ap-guangzhou.myqcloud.com/blog/article-cover/cmfkkq9a00001uhcg5k63cmt3.jpg)

