前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ServiceWorker入门

ServiceWorker入门

作者头像
用户2845596
发布2021-01-21 15:10:48
4220
发布2021-01-21 15:10:48
举报
文章被收录于专栏:劝学劝学

使用前提

  • 站点必须是https的,不过本地开发若是localhost访问,则本地可以是http协议
  • 浏览器支持情况,数据来源,caniuse.com
  • SW里面的API要求是异步的,所以localStorage不能使用,下面的demo可以看到大量的promise

基础使用

scope
  • scope作用域,一开始以为是同静态资源的作用域,后来才个发现这个作用域是hmtl的作用域,即只要html页面在这个作用域里,那页面的请求就会被fetch回调捕捉到。

下面的sw.js的路径是/,或是把sw.js的Header加上``头,当前涉及到运维的事都会比较麻烦啦。所以就是前端把sw.js放在/下会简单些。

设置成功后就输出这样子:reg success with scope https://domain.com/sw/

代码语言:javascript
复制
navigator.serviceWorker.register('/sw.js', {scope: '/'})
    .then(reg => {
        console.log('reg success with scope', reg.scope)
    })
    .catch(err => {
        console.log('serviceWorker reg fail', err)
    })
复制代码

代码语言:javascript
复制
/**
 * 
 * 改了这个文件,在浏览器里禁用了缓存,sw.js也不会再加载,在index.html里加上时间戳就会重新加载
 */
const VERSION = 'v2'

self.addEventListener('install', onInstall)
self.addEventListener('activate', onActivate)
self.addEventListener('fetch', onFetch)


function onInstall(event) {
    // waitUntil 的第一个参数是Promise
    event.waitUntil(
        Promise.all([
            self.skipWaiting(),
            // caches,不是cache
            caches.open(VERSION).then(cache => {
                // 在某一个cache集合里添加
                return cache.addAll([
                    // 这里的路径是相对于reg的scope的,而是网站的root
                    // 所以推荐写绝对路径
                    '/0.0.js',
                    '/2.2.js',
                    '/3.3.js',
                    '/4.4.js',
                ])
            })
        ])
    )
}

function onActivate(event) {
    let cacheWhiteList = [VERSION]

    event.waitUntil(
        caches.keys().then(function (keys) {
            return Promise.all(keys.map(function(key) {
                if (cacheWhiteList.indexOf(key) === -1) {
                    // 删除某一个Cache集合
                    return caches.delete(key).then(suc => {
                        return clients.claim()
                    })
                }
                // 强制更新service worker
                return clients.claim()
            }))
        })
    )
}

function onFetch(event) {
    let url = new URL(event.request.url)
    if (url.pathname !== event.request.pathname)) {
        return event.respondWith(
            fetch(event.request)
        )
    }

    // index.html的请求也会进来
    event.respondWith(
        caches.match(event.request).then(resp => {
            return resp || fetch(event.request, {
                credentials: 'omit'   // 不发送cookie
            }).then(response => {
                const cacheKey = VERSION
                return caches.open(cacheKey).then(cache => {
                    // put 得是某一个cache
                    cache.put(event.request, response.clone()).then(() => {
                    }).catch((e) => {
                    })
                    return response
                })
            })
        })
    )
}
复制代码
参考
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用前提
  • 基础使用
    • scope
      • 参考
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档