文件
k3s/apps/infra/net/nginx/static/sw-cdn.js
T
2025-08-13 19:36:52 +08:00

98 行
3.2 KiB
JavaScript

'use strict'
// Service Worker 配置 - 默认值
let config = {
cdnUrl: 'https://cdn.fillcode.com/',
serviceWorkerUrl: '/__static/sw-cdn.js',
staticRegex: /\.(js|css|png|jpg|jpeg|gif|svg|webp|woff|woff2|ttf|ico)$/,
debug: true,
}
// 监听配置更新消息
self.addEventListener('message', e => {
if (e.data.type !== 'CONFIG') return
config = e.data.config
if (config.debug) console.log('PWA-CDN: Config updated', config)
})
// 拦截网络请求
self.addEventListener('fetch', e => {
const url = new URL(e.request.url)
// 如果请求不是GET方法,直接返回
if (e.request.method !== 'GET') return
// 如果请求的域名不是当前页面的域名
if (url.origin !== self.location.origin) return
// 过滤__static路径下的请求
if (url.pathname.startsWith('/__static/')) return
// 如果请求的路径不匹配静态资源正则表达式,直接返回
if (!config.staticRegex.test(url.pathname)) return
// 判断是否是强制需要同源请求
const requiresSameOrigin = ['worker', 'sharedworker', 'serviceworker'].includes(e.request.destination)
// 如果是强制需要同源请求的资源类型,直接返回
if (requiresSameOrigin) return
// 开始处理静态资源请求
e.respondWith(handleStaticResource(e.request, url))
})
// 处理静态资源请求
async function handleStaticResource(request, url) {
// 生成CDN子路径
const hostname = self.location.hostname
const cdnPath = hostname.replace(/\./g, '-')
const targetUrl = config.cdnUrl + cdnPath + url.pathname + url.search
if (config.debug) console.log('PWA-CDN:', url.href, '->', targetUrl)
try {
// 创建新请求,保留原始缓存策略
const newRequest = new Request(targetUrl, {...request, mode: 'cors'})
// 请求目标域名,浏览器会自动处理缓存
const response = await fetch(newRequest)
if (!response.ok) throw new Error('Target domain response not ok: ' + response.status)
// 修复重定向问题
if([301, 302, 307, 308].includes(response.status)) {
const location = response.headers.get('location')
// 如果重定向的地址不是CDN地址,或者已经包含了CDN子路径,则返回原始响应
if(!location?.startsWith('/') || location.startsWith(`/${cdnPath}`)) return response
// 否则,重定向到新的CDN地址
const redirectUrl = new URL(location, config.cdnUrl + cdnPath)
if (config.debug) console.log('PWA-CDN: Redirecting to', redirectUrl.href)
return Response.redirect(redirectUrl.href, response.status)
}
return response
} catch (error) {
if (config.debug) console.warn('PWA-CDN: Fallback to original request for', url.href, error)
// 失败时回退到原始请求
return fetch(request)
}
}
// Service Worker 生命周期
self.addEventListener('install', () => {
if (config.debug) console.log('PWA-CDN: Service Worker installing')
self.skipWaiting().catch(console.error)
})
self.addEventListener('activate', () => {
if (config.debug) console.log('PWA-CDN: Service Worker activated')
self.clients.claim().catch(console.error)
})