使用Service Worker降级处理时的相对模块URL问题
Svelte Kit离线降级路由资源加载问题解答
问题场景
离线状态下结合Svelte Kit与Service Worker配置降级路由时,请求/test/会触发Service Worker返回根路径/的预渲染HTML。但该HTML中的模块预加载链接使用相对URL:
<link rel="modulepreload" href="./_app/immutable/start-5e8ef69f.js"> <link rel="modulepreload" href="./_app/immutable/chunks/index-cc4e69a6.js"> <link rel="modulepreload" href="./_app/immutable/chunks/stores-e8997401.js"> <link rel="modulepreload" href="./_app/immutable/chunks/preload-helper-b21cceae.js"> <link rel="modulepreload" href="./_app/immutable/chunks/store-535059b2.js">
浏览器会将这些相对URL解析为/test/_app/immutable/start-5e8ef69f.js这类子路径下的资源,导致无法找到文件;改用绝对URL则可避免此问题。
结论与解决方法
这不属于Svelte Kit的设计默认行为,而是场景适配时的配置疏漏,可通过以下方式解决:
配置Svelte Kit生成绝对URL
在svelte.config.js中,设置应用基础路径或开启预渲染绝对URL选项:/** @type {import('@sveltejs/kit').Config} */ const config = { kit: { paths: { base: '', // 部署在根目录可留空,子目录部署填对应路径 }, prerender: { absolute: true // 开启后预渲染会生成绝对URL的资源链接 } } }; export default config;在Service Worker中修正URL
在返回降级HTML响应前,通过正则替换将相对URL转换为绝对URL:self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request).then((response) => { if (response) return response; // 降级到根路径预渲染HTML return caches.match('/').then((rootResponse) => { if (!rootResponse) return fetch(event.request); // 克隆响应并修改内容 return rootResponse.text().then((html) => { const correctedHtml = html.replace(/href="\.\/_app\//g, 'href="/_app/'); return new Response(correctedHtml, { headers: rootResponse.headers }); }); }); }) ); });调整响应头辅助解析
检查Service Worker的降级逻辑,返回根路径HTML时,设置Content-Location响应头为/,部分浏览器可通过该头修正相对URL的解析基准。
内容的提问来源于stack exchange,提问作者leonat
相关产品推荐
相关产品推荐

