PWA离线仅加载首页问题及manifest scope属性配置咨询
嘿,我来帮你把manifest里的scope属性讲明白,顺便解决你离线只能加载首页的问题~
scope属性到底是什么? 简单说,scope就是给你的PWA划了个管控地盘:只有这个路径范围内的页面,才会被你的Service Worker(以下简称SW)接管。SW能做的事儿——比如拦截请求、提供离线缓存、推送通知——都只在这个地盘里生效;超出这个范围的页面,SW根本不会搭理它。
举个具体的例子:如果你的scope设成/Folder1/,那只有/Folder1/下的Page A会被SW管,/Folder2/里的Page B就不在这个地盘里,离线时自然加载不了缓存的内容。
scope? 你的PWA跨了两个文件夹(Folder1和Folder2),要让SW同时管到两个页面,scope得设成能覆盖这两个路径的范围:
- 最稳妥的选择是设为根路径:
"scope": "/"。这样整个域名下的所有页面都会被这个SW接管,不管是Folder1还是Folder2里的内容,都能享受到SW的离线支持。 - 如果你不想让SW管控整个域名(比如还有其他无关页面),也可以设为包含两个文件夹的父路径,但看你的结构,两个文件夹都是根目录的子文件夹,根路径是最省心的设置。
不过光改scope还不够,你得再检查这几个关键点,才能让Page B离线也能加载:
1. 修正SW的缓存路径
你的SW里缓存列表写的是:
const cachedData = [ './', '../Folder2/Page B' ];
这里的相对路径是基于SW所在的Folder1目录解析的,但实际请求Page B时,浏览器的URL是/Folder2/Page B,和缓存里的../Folder2/Page B路径写法不匹配,导致离线时caches.match(req)找不到对应的缓存。
建议改成绝对路径,确保缓存路径和实际请求URL完全一致:
const cachedData = [ '/Folder1/', '/Folder2/Page B' ];
2. 确认SW的注册逻辑没问题
- Page A里的注册代码
navigator.serviceWorker.register('sw.js')是对的,因为Page A在Folder1,这个路径指向/Folder1/sw.js。 - Page B里的
navigator.serviceWorker.register('../Folder1/sw.js')路径也没问题,而且因为你已经在manifest里把scope设为/,SW允许管控比自身所在目录更大的范围(manifest的scope优先级高于SW的默认作用域)。
3. 验证缓存是否成功安装
你可以打开浏览器DevTools的「Application」面板,找到「Cache Storage」,查看app-static缓存里是否包含了Page B的资源。如果没找到,检查下路径是否写错,或者看Console里的SW安装日志,排查是否有报错。
内容的提问来源于stack exchange,提问作者David Raouf

