Service Worker注册报SecurityError,主因是HTTPS未配置:localhost虽被豁免,但自定义域名(如dev.example.com)必须配可信HTTPS证书;推荐用mkcert生成并配置开发服务器,同时确保register()在DOM就绪后执行、路径为根相对路径。

本地开发时 Service Worker 报 SecurityError: Failed to register a ServiceWorker,基本就是 HTTPS 环境没配对。localhost 默认被浏览器豁免,但一旦你用了自定义域名(如 dev.example.com)、启用了严格模式、或测试 PWA 安装流程,就绕不开 HTTPS。下面几招能真正解决问题,不是临时凑合。
用 mkcert 快速生成可信本地 HTTPS 证书
别再手写 openssl 命令——mkcert 是目前最省心的方案,生成的证书会被 Chrome、Firefox、Safari 直接信任。
- 安装 mkcert:macOS 执行
brew install mkcert nss;Windows 用 Chocolatey:choco install mkcert - 初始化本地 CA:
mkcert -install(需管理员/root 权限) - 为你的开发域名生成证书:
mkcert dev.example.com localhost 127.0.0.1→ 输出dev.example.com-key.pem和dev.example.com.pem - 把这两个文件放进项目目录(如
/cert/),后续配置开发服务器时引用
配置开发服务器启用 HTTPS 并绑定自定义域名
光有证书还不够,服务器得用它启动,并且让浏览器能通过域名访问。
-
改 hosts 文件:添加一行
127.0.0.1 dev.example.com(Windows 在C:\Windows\System32\drivers\etc\hosts,Mac/Linux 在/etc/hosts) -
Vite 示例:
import { defineConfig } from 'vite'
import fs from 'fs'
export default defineConfig({
server: {
host: 'dev.example.com',
port: 8080,
https: {
key: fs.readFileSync('./cert/dev.example.com-key.pem'),
cert: fs.readFileSync('./cert/dev.example.com.pem')
}
}
}) -
Webpack DevServer 示例:在
devServer中加https: true和key/cert字段,同时设host: 'dev.example.com'和allowedHosts: ['.example.com']
确保 Service Worker 注册逻辑不出错
HTTPS 配好了,注册仍失败?大概率是脚本执行时机或路径问题。
- 注册代码必须放在
<script>标签中,且在</body>前或监听DOMContentLoaded,不能等window.onload或包裹在异步函数里 - 路径必须是根相对路径:
navigator.serviceWorker.register('/sw.js'),不能写'./sw.js'或'sw.js' - 检查 Network 面板:过滤
sw.js,确认返回状态码是 200,且响应头不含Cache-Control: no-cache(Chrome 会拒绝解析) - 打开 DevTools → Application → Service Workers,勾选 “Update on reload”,刷新页面看是否显示 “Ready” 状态
调试时绕过常见干扰项
有些现象看似是 HTTPS 问题,其实是生命周期或作用域卡住了。
- 新 SW 卡在
waiting状态?在install事件里加self.skipWaiting(),并在activate里调clients.claim()强制接管 - fetch 事件不触发?先确认请求是同源、由页面主动发起(
<img>、fetch()等),且不是跨域资源未带 CORS 头 - 想快速验证是否生效?在
sw.js开头加console.log('SW loaded'),然后在 DevTools Console 左上角环境切换器中选service_worker查看输出

















