Service Worker 无法直接镜像第三方版本,因其不能拦截非同源或非受控的跨域请求;只能通过将远程资源本地化为可控路径(如 /mirrors/de/v1.2.0/)、预缓存、版本化缓存命名及精准 fetch 路由来实现伪镜像离线可用。

Service Worker 的 fetch 拦截本身不提供“版本镜像”功能,但可以配合缓存命名、请求重写与预缓存逻辑,模拟出类似 gh_mirrors/de/deprecated-version 这类静态资源镜像的离线可用行为——前提是所有目标资源必须由你的站点主动发起请求,且路径可预测。
为什么不能直接“镜像第三方版本”
浏览器禁止 Service Worker 拦截非同源、非受控的第三方请求。比如你无法让自己的 sw.js 去接管用户访问 https://gh_mirrors/de/deprecated-version/app.js 时的响应,除非:
- 该 URL 是你页面中
<script src="https://gh_mirrors/de/deprecated-version/app.js"></script>主动加载的(同源或 CORS 配置允许) - 你已在
install阶段显式调用caches.open('mirror-v1').addAll([...])预缓存了该 URL 对应的内容 - 你在
fetch事件中对匹配该域名和路径的请求做了caches.match()+respondWith()路由
否则,即使 URL 看起来像镜像路径,浏览器也会按常规跨域策略处理,SW 无权返回缓存或伪造响应。
如何实现“伪镜像”缓存策略
关键不是拦截任意镜像域名,而是把镜像资源当成你自己的静态资产来管理。例如,你想让 /mirrors/de/v1.2.0/main.js 在离线时仍能加载,就得让它成为你可控路径的一部分:
- 构建时将远程镜像资源下载并本地化:用脚本把
https://gh_mirrors/de/deprecated-version/main.js下载到/mirrors/de/v1.2.0/main.js,并写入sw.js的ASSETS_TO_CACHE列表 - 在
install事件中使用带版本号的 cache name,如caches.open('mirror-v1.2.0'),避免与其他版本冲突 - 在
fetch事件中,用正则匹配/mirrors/de/v\d+\.\d+\.\d+/.*路径,然后只查对应版本的 cache,不 fallback 到网络 - 若需支持多版本共存,可在
activate事件中清理旧 cache:caches.delete('mirror-v1.1.0')
示例片段(sw.js 中):
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
// 匹配本地化的镜像路径
if (/^\/mirrors\/de\/v\d+\.\d+\.\d+\//.test(url.pathname)) {
const cacheName = 'mirror-' + url.pathname.split('/')[3]; // 提取 v1.2.0
event.respondWith(
caches.match(event.request, { cacheName })
.then(res => res || new Response('', { status: 404 }))
);
}
});
fetch 拦截中容易忽略的兼容性陷阱
看似简单的路径匹配,在真实环境中常因以下原因失败:
-
request.destination为'document'时,浏览器可能自动追加index.html,导致缓存 key 不一致;建议在install阶段也缓存/mirrors/de/v1.2.0/对应的 HTML 入口 - 某些 CDN 或镜像服务对
Referer或User-Agent有校验,直接fetch(request)可能 403;需克隆 request 并显式设置 headers:new Request(request, { headers: new Headers({ 'User-Agent': 'Mozilla/5.0' }) }) -
caches.match()默认不匹配 query 参数;若镜像 URL 带?t=123,需传{ ignoreSearch: true }才能命中缓存 - HTTPS 环境下,
http://镜像地址无法被缓存(混合内容限制),必须确保所有镜像资源走 HTTPS
真正难的不是写几行 respondWith(),而是让每个镜像路径的请求都精确落在你预设的缓存命名空间里,并且在版本切换时旧缓存不干扰新逻辑——这要求构建流程、路径约定和 SW 生命周期三者严格对齐。

















