跳到主要内容

Service Worker

常见使用场景

  • 应用后台同步
  • 浏览器通知推送
  • 拦截网络请求
  • 自定义请求缓存

特点及限制

  • 事件驱动,非阻塞,完全异步,无法使用同步的 XMLHttpRequest 和 localStorage/sessionStorage
  • 运行在非主线程,无法访问 DOM
  • Firefox 处于无痕浏览模式、禁用了历史记录或启用了“在 Firefox 关闭时清除历史记录”时无法使用
  • Chrome 阻止所有 Cookie 时无法使用
  • 需要运行在安全的上下文中,通常指 HTTPS 网页,本地开发时的 localhost 也被认为是 secure origin
  • Firefox 147 (2026-01-13) 版本才在 Service Worker 中支持 ECMAScript modules

参考来源:

拦截网络请求示例

前端加载 HTML 压缩包,并拦截相关网络请求,返回压缩包中的文件内容

<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>htmlzip viewer</title>
</head>

<body>
<input type="file" id="fileinput" accept=".zip" disabled>
<script type="module">
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then((reg) => {
const fileInput = document.getElementById('fileinput')
fileInput.disabled = false
fileInput.addEventListener('change', (event) => {
console.log(event)
if (fileInput.files.length > 0) {
navigator.serviceWorker.controller.postMessage({
type: 'FILE_UPLOAD',
file: fileInput.files[0]
})
}
})
})
navigator.serviceWorker.addEventListener('message', (event) => {
console.log(event)
if (event.data && event.data.type === 'FILE_UPLOAD_OK') {
const filename = event.data.filename
window.location.href = `/view/${encodeURIComponent(filename)}/`
}
})
await navigator.serviceWorker.register('sw.js', { type: 'module' })
} else {
window.alert('navigator.serviceWorker not found')
}
</script>
</body>

</html>