Service Worker 中的概念
Service-Worker-Allowed 响应头
发布于 更新于
Service-Worker-Allowed 是随 Service Worker 脚本返回的 HTTP 响应标头,用来设置注册可请求的最大路径 scope,让作用域可以超出脚本所在目录。
浏览器与平台支持
链接到“浏览器与平台支持”一节按照 Service Workers 规范,注册 Service Worker 需要安全上下文。
工作原理
链接到“工作原理”一节响应不带这个标头时,Service Workers 规范根据脚本 URL 的目录得出最大允许 scope。因此,位于
/product/sw.js 的脚本默认以 /product/ 为最大值。随脚本返回
Service-Worker-Allowed: / 后,注册可以请求 /。
标头的值是相对脚本 URL 解析的 URL。规范会比较请求的 scope 路径与该最大路径。请求的 scope
路径不以最大允许路径开头,或标头 URL 与脚本 URL 不同源,都会使注册任务以
SecurityError 拒绝。如果标头值无法解析为 URL,fetch 会以 network error 完成;随后更新算法
会以 TypeError 拒绝该任务,除非此前已调用 SecurityError。
服务器必须把标头附加到 Service Worker 脚本响应,而不是调用 register() 的页面。然后,
客户端才能请求对应的更宽 scope。
返回根路径最大 scope
链接到“返回根路径最大 scope”一节此 Node HTTP 处理器随 /product/sw.js 返回该标头。Service Worker 正文是有效的 JavaScript,
安装时不会新增缓存条目。
import { createServer } from 'node:http';
createServer((request, response) => { if (request.url === '/product/sw.js') { response.writeHead(200, { 'content-type': 'text/javascript', 'service-worker-allowed': '/', }); response.end("self.addEventListener('install', () => {});"); return; }
response.writeHead(404); response.end('Not found');}).listen(8080);带有此响应时,规范允许 /product/sw.js 请求 / 作为注册 scope。
注册更宽 scope 并提供回退
链接到“注册更宽 scope 并提供回退”一节注册前先检测是否支持 Service Worker。注册失败时,保留页面的在线功能并报告部署错误,不要假定 Worker 已经控制页面。
if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/product/sw.js', { scope: '/' }) .then((registration) => { console.log('Registered scope:', registration.scope); }) .catch((error) => { console.error('Service worker registration failed:', error); document.documentElement.dataset.offline = 'unavailable'; });} else { document.documentElement.dataset.offline = 'unsupported';}请求的 scope 必须位于标头指定的最大范围内。例如,Service-Worker-Allowed: /product/
不允许 { scope: '/' }。
另请参阅
链接到“另请参阅”一节- Service Worker 注册与 scope
- Service Worker 生命周期
- Service Worker 调试
- Service Workers: Service-Worker-Allowed(w3c.github.io)
- Service-Worker-Allowed header(MDN)
规范
| 规范 | 状态 |
|---|---|
| Service Worker | W3C 草案 |
| Service Workers: Service-Worker-Allowed | W3C 草案 |
- 图例
- 支持
- 部分支持
- 需开启标志
- 不支持
- 未知
| 浏览器 / 平台 | 支持 | 版本 | 置信度 | 来源 | 备注 |
|---|---|---|---|---|---|
| Chrome (Desktop)# | 支持 | 40 | 高 | 来源 | — |
| Chrome (Android)# | 支持 | 40 | 高 | 来源 | 1 |
| Edge (Desktop)# | 支持 | 17 | 高 | 来源 | — |
| Firefox (Desktop)# | 支持 | 44 | 高 | 来源 | — |
| Firefox (Android)# | 支持 | 44 | 高 | 来源 | 2 |
| Safari (macOS)# | 支持 | 11.1 | 高 | 来源 | — |
| Safari (iOS)# | 支持 | 11.3 | 高 | 来源 | 3 |
| Samsung Internet# | 支持 | 4.0 | 高 | 来源 | 4 |
| WebView (Android)# | 支持 | 40 | 高 | 来源 | 5 |
- 由 browser-compat-data 镜像自 Chrome 的数据推导。
- 由 browser-compat-data 镜像自 Firefox 的数据推导。
- 由 browser-compat-data 镜像自 Safari 的数据推导。
- 由 browser-compat-data 镜像自 Chrome Android 的数据推导。
- 由 browser-compat-data 镜像自 Chrome Android 的数据推导。