Service Worker


多次注册 sw 会覆盖

不会拦截 manifest 和 sw 脚本

LocalStorage 和 SessionStorage 和 Cookie 是同步的所以不能用!

不能在sw中储存变量,sw停止运行后数据不会保存;

可以通过 iframe 预加载 sw,缓存静态数据,sw 的服务器需要调整 csp;

和 WindowClient 交互使用 postMessage

sw 中不能添加跨域非 cors 资源(不透明资源)、非http(?)到 Cache;

sw 取消注册返回一个promise, 可以执行callback, 例如删除后端的 push 订阅信息, 另外通过 PUSH 服务器的错误返回删除

使用 sw 可能需要使用 Navigation Preloads:activate 中启动,fetch 事件中应用预请求响应
sw 的 clients.get(id) 返回 Client,每次返回不是同一个对象的引用
在 firefox 中,只有notification(via:sw reg) click event 才能 clients.openWindow . // 默认使用相对路径(相对sw文件)
还可以直接(不需要用户交互)导航受控WindowClient.navigate()

后台同步 API:在特定时间发生 sync 事件,在sw中执行一些同步的任务。分一次性同步(连线时)和周期性同步
// 它的优点是能自动更新, 更新规则在注册时设定。

// 正在设计 backgroundFetch API,不兼容普通 fetch,成功只触发 sw 中的事件

sw 文件中的 this 是 ServiceWorkerGlobalScope, 它的 install 事件对象 是 ExtendableEvent

注册scope:只能注册同源的脚本, ServiceWorkerContainer.register(scriptURL, options).then(function(ServiceWorkerRegistration){}), 在范围内的页面使用同一个 sw;最大范围是 sw 脚本的位置;指定 sw 范围Service-Worker-Allowed 头(js 文件响应头), 跟 scope 不同将注册失败
// 一个 scope 只可以作为第三方域名注册Foreign Fetch,用于该sw处理其它域名的请求(foreignfetch事件)
// 如果字体供应商在客户机上注册sw,提供离线服务;
// foreignfetch 的 respondWith可以设置origin,控制响应是否透明
// 注册方式使用HTTP Header: // 如:单独请求一张图片注册sw
Link: ; rel="serviceworker"; scope="/"
// Service-Worker-Allowed 响应头方便在 sw 范围内禁用某个页面的sw
// Service-Worker-Max-Age 自动卸载 sw

检测网络链接: event.respondWith(fetch(url).catch(e => new Rsponse('hehe')))
respondWith 的参数可以为一个promise,不能为undefined(caches没有match到),出错就立即正常返回,外层promise catch的时候已经返回不能在使用respondWith了。

sw 优先级大于 AppCache

Service worker运行在一个 worker 的环境中:因此,他不会用 dom 的访问权,并且是在主线程之外的另一个线程中运行来加速你的APP,所以它不会造成阻 塞。它的设计是完全异步的,因此,同步的 XHR 请求和 localStorage 都不能应用在 service worker 中(能使用IndexDB)。 firefox 的 swg 中的 console.log 打印在安装页面控制台(自己没有console对象)并且 toString了。。。chrome在注册页面的控制台里面可以像调试iframe一样调试sw 脚本。

因为 oninstall/onactivate 可能需要一些时间去完成, service worker 标准提供了一个 waitUntil 方法,当 oninstall 或者 onactivate 时被调用, 接受一个 promise参数,promise完成才结束这个事件,ServiceWorkerGlobalScope.skipWaiting() 返回一个promise:强制将等待的sw变为激活(发生active事件)的sw,配合Clients.claim()即时更新sw
跨域请求的响应可以在 respondWith 的响应中添加原始event.orgin覆盖默认的当前origin
// sw 可以监听多个 fetch 事件,但只有一个 respondWith 有用其他抛出错误
// xhr 等跨域fetch资源需要响应头加允许源字段;

ServiceWorkerContainer.ready 等方法得到注册的ServiceWorkerRegistration,即ServiceWorkerGlobalScope.registration
基于它可以实现消息推送(Push API),静默更新以及地理围栏等服务,但是目前它首先要具备的功能是拦截和处理网络请求,包括可编程的响应缓存管理(Cache API)
解决App Cache在多页应用上的痛点用promise
在不被使用的时候,它会自己终止,而当它再次被用到的时候(例如收到push消息),会被重新激活
Service worker 权限很大(劫持连接,伪造和过滤响应),所以要防止它本身被坏人篡改利用(HTTPS
Service Worker 脚本安装完成会自身触发 install 事件,可以在完成后缓存文件
如果所有的第一个文件被缓存成功了,那么 service worker 就安装成功
如果 response 是一个Stream,那么它的 body 只能被读取一次,需要 clone 这个请求。
安装之后 refresh or page load, service worker 的脚本文件会被下载, 而且至少每24小时被下载一次。只要服务器上的文件和本地文件有一个字节不同,它们就被判定为需要更新。
所有使用sw的页面被关闭之后(在不被使用的时候,老的 service worker 线程被杀死(sw stop),新的 servicer worker 正式生效,它的activate事件被触发(这时可以清除旧缓存)。

// 利用 sw 可以根据需要修改请求,比如按网络环境请求图像