Angular 6中Service Worker与子域名的协作及缓存配置问题
嘿,我来帮你理清Angular Service Worker和子域名的协作逻辑,还有怎么配置才能缓存所有子域名的资源!
首先得明确一个核心点:Service Worker是严格绑定同源的。浏览器的同源策略规定,注册在example.com的Service Worker,只能控制example.com域名下的页面和请求,没法直接管abc.example.com、xyz.example.com这类子域名——因为它们属于不同的源。
你的场景下子域名的表现
按照你列出的步骤:
- 用户访问
example.com,Service Worker成功注册 - 当用户访问
abc.example.com或xyz.example.com时,这两个子域名的页面不会被example.com的Service Worker控制。如果这些子域名也需要Service Worker能力,你得在每个子域名下单独部署Angular应用(至少要部署Service Worker文件和对应的ngsw-config.json),然后各自注册Service Worker。
如何配置缓存所有子域名的资源
如果你的需求是让主域名的Service Worker缓存子域名的静态资源或API请求,或者让子域名的Service Worker缓存其他子域名的资源,可以按下面的方式调整配置:
1. 配置assetGroups缓存子域名静态资源
在assetGroups里新增一个分组,明确指定要缓存的子域名资源路径。比如要缓存abc.example.com和xyz.example.com下的所有assets:
{ "name": "subdomain-assets", "installMode": "lazy", "updateMode": "prefetch", "resources": { "urls": [ "https://abc.example.com/assets/**", "https://xyz.example.com/assets/**" ] } }
⚠️ 注意:跨源缓存需要目标子域名的服务器配置CORS响应头(比如Access-Control-Allow-Origin: https://example.com),否则浏览器会阻止Service Worker缓存这些资源。
2. 配置dataGroups缓存子域名API请求
你当前的配置里已经用了https://**.api.example.com/**,这个多级通配符可以匹配所有api.example.com的子域名(比如foo.api.example.com、bar.api.example.com)。如果想更明确,也可以用单级通配符*来匹配一级子域名:
{ "name": "database", "urls": [ "https://*.api.example.com/pl/**", "https://*.api.example.com/en/**" ], "cacheConfig": { "maxSize": 100000000, "maxAge": "3d", "timeout": "2m" } }
这个配置会缓存所有api.example.com子域名下的/pl/和/en/路径的API请求。
整合后的完整ngsw-config.json示例
下面是把上述配置整合到你现有文件后的版本:
{ "index": "/index.html", "assetGroups": [ { "name": "app", "installMode": "prefetch", "resources": { "files": [ "/favicon.ico", "/index.html", "/*.css", "/*.js" ] } }, { "name": "assets", "installMode": "lazy", "updateMode": "prefetch", "resources": { "files": [ "/assets/**" ] } }, { "name": "fonts", "resources": { "urls": [ "https://fonts.googleapis.com/**", "https://fonts.gstatic.com/**" ] } }, { "name": "subdomain-assets", "installMode": "lazy", "updateMode": "prefetch", "resources": { "urls": [ "https://abc.example.com/assets/**", "https://xyz.example.com/assets/**" ] } } ], "dataGroups": [ { "name": "database", "urls": [ "https://*.api.example.com/pl/**", "https://*.api.example.com/en/**" ], "cacheConfig": { "maxSize": 100000000, "maxAge": "3d", "timeout": "2m" } } ] }
额外关键提醒
- 子域名独立部署Service Worker:如果每个子域名是独立的Angular应用,必须各自部署Service Worker和配置文件,才能控制各自的页面。主域名的Service Worker无法跨源接管子域名页面。
- 作用域限制:即使你在注册Service Worker时指定
scope选项,也没法突破同源策略,作用域只能限定在当前域名的路径下,不能跨到子域名。 - CORS必配:所有跨源的资源请求,都需要目标服务器配置允许当前源访问的CORS头,否则Service Worker无法完成缓存。
内容的提问来源于stack exchange,提问作者Aranganathan

