注意 , 最后的self.clients.claim()方法设置本身为active的service worker 。
Fetch 事件当有网络请求时这个事件被触发 。它调用respondWith()方法来劫持 GET 请求并返回:
- 缓存中的一个静态资源 。
- 如果 #1 失败了 , 就用 Fetch API(这与 service worker 的fetch 事件没关系)去网络请求这个资源 。然后将这个资源加入缓存 。
- 如果 #1 和 #2 都失败了 , 那就返回一个适当的值 。
// application fetch network dataself.addEventListener('fetch', event => {// abandon non-GET requestsif (event.request.method !== 'GET') return;let url = event.request.url;event.respondWith(caches.open(CACHE).then(cache => {return cache.match(event.request).then(response => {if (response) {// return cached fileconsole.log('cache fetch: ' + url);return response;}// make network requestreturn fetch(event.request).then(newreq => {console.log('network fetch: ' + url);if (newreq.ok) cache.put(event.request, newreq.clone());return newreq;})// app is offline.catch(() => offlineAsset(url));});}));});最后这个offlineAsset(url)方法通过几个辅助函数返回一个适当的值:// is image URL?let iExt = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp'].map(f => '.' + f);function isImage(url) {return iExt.reduce((ret, ext) => ret || url.endsWith(ext), false);}// return offline assetfunction offlineAsset(url) {if (isImage(url)) {// return imagereturn new Response('<svg role="img" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg"><title>offline</title><path d="M0 0h400v300H0z" fill="#eee" /><text x="200" y="150" text-anchor="middle" dominant-baseline="middle" font-family="sans-serif" font-size="50" fill="#ccc">offline</text></svg>',{ headers: {'Content-Type': 'image/svg+xml','Cache-Control': 'no-store'}});}else {// return pagereturn caches.match(offlineURL);}}offlineAsset()方法检查是否是一个图片请求 , 如果是 , 那么返回一个带有 “offline” 字样的 SVG 。如果不是 , 返回 offlineURL 页面 。开发者工具提供了查看 Service Worker 相关信息的选项:

文章插图
2020042302.png
在开发者工具的 Cache Storage 选项列出了所有当前域内的缓存和所包含的静态文件 。当缓存更新的时候 , 你可以点击左下角的刷新按钮来更新缓存:

文章插图
2020042303.png
不出意料 , Clear storage 选项可以删除你的 service worker 和缓存:

文章插图
2020042304.png
2.4 第四步:创建一个可用的离线页面离线页面可以是一个静态页面 , 来说明当前用户请求不可用 。然而 , 我们也可以在这个页面上列出可以访问的页面链接 。
在main.js中我们可以使用 Cache API。然而API 使用promises , 在不支持的浏览器中会引起所有javascript运行阻塞 。为了避免这种情况 , 我们在加载另一个 /js/offlinepage.js 文件之前必须检查离线文件列表和是否支持 Cache API。
// load script to populate offline page listif (document.getElementById('cachedpagelist') && 'caches' in window) {var scr = document.createElement('script');scr.src = https://www.isolves.com/it/cxkf/bk/2020-04-26/'/js/offlinepage.js';scr.async = 1;document.head.appendChild(scr);}/js/offlinepage.js locates the most recent cache by version name, 取到所有 URL的key的列表 , 移除所有无用 URL , 排序所有的列表并且把他们加到 ID 为cachedpagelist的 DOM 节点中:// cache nameconstCACHE = '::PWAsite',offlineURL = '/offline/',list = document.getElementById('cachedpagelist');// fetch all cacheswindow.caches.keys().then(cacheList => {// find caches by and order by most recentcacheList = cacheList.filter(cName => cName.includes(CACHE)).sort((a, b) => a - b);// open first cachecaches.open(cacheList[0]).then(cache => {// fetch cached pagescache.keys().then(reqList => {let frag = document.createDocumentFragment();reqList.map(req => req.url).filter(req => (req.endsWith('/') || req.endsWith('.html')) && !req.endsWith(offlineURL)).sort().forEach(req => {letli = document.createElement('li'),a = li.appendChild(document.createElement('a'));a.setAttribute('href', req);a.textContent = a.pathname;frag.appendChild(li);});if (list) list.appendChild(frag);});})});
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 如何快速处理mysql连接数占满的问题?
- Go的泛型真的要来了—如何使用以及它们是怎么工作的
- 把猫送人了猫会伤心吗?
- Mysql 单表适合的最大数据量是多少?如何优化其性能?
- 在 Excel 中如何正确输入身份证号?
- 网站推广如何应对劲风算法?劲风算法又是什么?
- PDF如何转Excel?PDF转Excel的操作方法!
- 如何在淘宝网开店步骤 淘宝开网店需要注意什么
- 如何识别洛神花加色素,洛神花茶的功效及其作用
- 淘宝怎样升级最新版本 淘宝如何快速升级
