Polymer应用中Service Worker是否干扰Firebase Hosting重写?缓存问题求助
从你的描述和无痕模式的测试结果来看,Service Worker的预缓存确实是核心问题——Polymer的Service Worker会拦截页面请求,直接返回本地缓存的index.html,完全绕过了Firebase Hosting的重写规则,自然不会触发你的test函数。下面是几个兼顾Service Worker缓存优势和重写规则触发的解决方案:
1. 修改Service Worker的缓存策略,跳过需要触发函数的路径
Polymer通常会用sw-precache或者Workbox生成Service Worker,你需要调整缓存规则,让页面导航类请求不被Service Worker缓存,而是直接走网络请求(从而触发Hosting重写)。
如果你使用Workbox,可以在配置里排除index.html的预缓存:
// workbox-config.js module.exports = { globDirectory: 'build/es5-bundled/', globPatterns: ['**/*.{js,css,png}'], // 只缓存静态资源,排除html swDest: 'build/es5-bundled/sw.js' };
或者直接在Service Worker的fetch事件里做判断,让导航请求绕过缓存:
self.addEventListener('fetch', (event) => { // 页面导航请求(比如输入URL、刷新页面)直接走网络 if (event.request.mode === 'navigate') { event.respondWith(fetch(event.request)); return; } // 静态资源继续使用缓存优先策略 event.respondWith( caches.match(event.request).then((response) => { return response || fetch(event.request); }) ); });
这样页面请求会触发Hosting重写调用函数,而JS、CSS、图片等静态资源依然能享受Service Worker的缓存加速。
2. 优化函数返回的缓存头,避免过度缓存
你已经设置了短时效的缓存头,可以再补充must-revalidate,确保缓存过期后必须重新验证,避免浏览器或CDN直接使用过期内容:
res.set('Cache-Control', 'public, max-age=10, s-maxage=10, must-revalidate');
不过这是辅助措施,核心还是要解决Service Worker的拦截问题,因为Service Worker的缓存优先级高于浏览器缓存。
3. 强制更新已部署的Service Worker
修改Service Worker配置后,需要让用户浏览器替换旧的缓存版本。最简单的方法是修改Service Worker文件的内容(比如加个版本号注释),浏览器检测到文件变化后会自动更新:
// sw.js - v2.0.0(修改版本号触发更新) ...
你也可以在Polymer应用中添加Service Worker更新检测逻辑,主动提示用户刷新页面完成更新。
关于登录状态的疑问
登录状态不会直接导致重写规则不触发,除非你的Service Worker或函数逻辑中,根据登录状态做了特殊缓存处理(比如缓存了未登录状态的index.html)。但从你的情况来看,问题根源是Service Worker拦截了请求,和登录状态无关。
最后提醒:修改后一定要在非无痕模式下测试,确保旧的Service Worker被更新,否则可能还是会看到缓存的旧行为。
内容的提问来源于stack exchange,提问作者TheBen

