Odoo16 Safari特定页面ServiceWorker报错求适配解决方案
Odoo16 Safari 16.3~17.3 ServiceWorker 兼容性修复方案
问题背景
你遇到的是Safari 16.3到17.3版本之间的WebKit内核bug:当ServiceWorker调用FetchEvent.respondWith处理特定请求时,会抛出NotSupportedError,导致页面无法加载。清空缓存或用隐私窗口能临时解决,是因为这些操作会禁用或重置ServiceWorker,但常规浏览时ServiceWorker会自动注册重载,导致问题复发。
修复思路
直接修改Odoo的service-worker.js,针对受影响的Safari版本:
- 跳过触发bug的请求(比如
/event路径)的ServiceWorker拦截,让浏览器原生加载 - 为
respondWith添加错误捕获,避免单个请求错误导致ServiceWorker崩溃重载
具体操作步骤
1. 定位ServiceWorker文件
Odoo默认的service-worker.js在addons/web/static/src/service-worker.js,如果是自定义模块或主题的ServiceWorker,查找对应静态资源目录下的文件。
2. 添加Safari版本检测函数
在文件顶部插入以下代码:
function isAffectedSafari() { const ua = navigator.userAgent; const versionMatch = ua.match(/Version\/(\d+)\.(\d+)/); // 排除Chrome伪装的Safari UA,只匹配纯Safari if (!versionMatch || !ua.includes('Safari') || ua.includes('Chrome')) return false; const major = parseInt(versionMatch[1], 10); const minor = parseInt(versionMatch[2], 10); // 匹配16.3 < 版本 < 17.3 return (major === 16 && minor > 3) || (major === 17 && minor < 3); }
3. 修改Fetch事件处理逻辑
找到原有的self.addEventListener('fetch', ...)代码块,修改为:
self.addEventListener('fetch', (event) => { // 针对受影响的Safari版本,直接放行/event路径请求 if (isAffectedSafari()) { const requestUrl = new URL(event.request.url); if (requestUrl.pathname.includes('/event')) { return; // 不使用ServiceWorker拦截,交给浏览器直接处理 } // 如果其他页面也有类似问题,可以移除path判断,全局放行 } // 保留Odoo原有的ServiceWorker缓存逻辑 // --- 此处保留原fetch事件内的代码 --- try { event.respondWith( // 原有的缓存/网络处理逻辑,比如: caches.match(event.request) .then(cachedResponse => cachedResponse || fetch(event.request)) ); } catch (err) { // 捕获NotSupportedError,直接放行 if (err.name === 'NotSupportedError') return; throw err; } });
4. 生效操作
- 重启Odoo服务,确保静态资源更新
- 在Odoo后台强制刷新静态资源(设置->技术->参数->系统参数,更新
web.base.url或手动触发资源刷新) - 通知访客刷新页面,让浏览器获取新版本的ServiceWorker
验证
- 用受影响版本的Safari访问
/event页面,确认无错误 - 跳转其他页面后返回
/event,验证问题不复现 - 测试Firefox、Chrome及其他Safari版本,确保功能正常
内容的提问来源于stack exchange,提问作者Ahrimann Steiner
相关产品推荐
相关产品推荐

