diff --git a/3DTank/tools/wss_server.js b/3DTank/tools/wss_server.js index ace5de8..1d76140 100644 --- a/3DTank/tools/wss_server.js +++ b/3DTank/tools/wss_server.js @@ -511,8 +511,17 @@ WsServer.on('connection', (Client, Req) => { let Upstream = null; const Pending = []; // 上游未就绪时暂存竞态帧(握手帧常比上游 TLS 建连更早到达),一连上立即按原序补发 + // 握手头:把客户端**真实的** Origin / User-Agent / Referer 透传给上游(与浏览器直连时一致)。 + // 不能用写死的 origin:真实服务器可能按 Origin 选择构建/配置,写死会让响应与本地构建对不上, + // 表现为客户端握手失败自行断开(close code 1005)。 + const UpHeaders = { + 'user-agent': Req.headers['user-agent'] || UPSTREAM_HEADERS['user-agent'], + origin: Req.headers['origin'] || UPSTREAM_HEADERS.origin, + referer: Req.headers['referer'] || UPSTREAM_HEADERS.referer, + }; + // 转发:客户端帧**原样直发**;上游未就绪时暂存,open 后按原序补发(不重放、不改字节)。 - Upstream = new Ws(UPSTREAM, { headers: UPSTREAM_HEADERS, rejectUnauthorized: false }); + Upstream = new Ws(UPSTREAM, { headers: UpHeaders, rejectUnauthorized: false }); Upstream.binaryType = 'nodebuffer'; Upstream.on('open', () => { State.Log('上游已连接: ' + UPSTREAM + ',补发暂存 ' + Pending.length + ' 帧'); diff --git a/3dtank.com/play/static/js/main.9f4e7a89.js b/3dtank.com/play/static/js/main.9f4e7a89.js index 3866ec6..ad6f3eb 100644 --- a/3dtank.com/play/static/js/main.9f4e7a89.js +++ b/3dtank.com/play/static/js/main.9f4e7a89.js @@ -131,15 +131,23 @@ var __webpack_modules__ = window.__modules__; // 作用域必须是 /:首页 / 发起的 /play/... 请求才会被接管(serve.js 已放行 Service-Worker-Allowed) // 用途:把 unpacked 下的散装小文件用单包就地命中(hornet_sw.js 内置单包缓存) if ('serviceWorker' in navigator && /^(localhost|127\.0\.0\.1|\[::1\])$/.test(location.hostname)) { - navigator.serviceWorker - .register('/hornet_sw.js', { scope: '/', updateViaCache: 'none' }) - .then(function (Reg) { - console.log('[Hornet] Service Worker 就绪(作用域 ' + Reg.scope + '),unpacked 小文件将由单包命中'); - return Reg.update(); - }) - .catch(function (Err) { - console.warn('[Hornet] Service Worker 注册失败: ' + (Err && Err.message)); + if (/#nosw/.test(location.hash)) { + // #nosw:注销已注册的 Service Worker(清除单包缓存接管),用于排查镜像页问题;生效需再刷新一次 + navigator.serviceWorker.getRegistrations().then(function (Regs) { + Regs.forEach(function (Reg) { Reg.unregister(); }); + console.warn('[Hornet] #nosw:已注销 Service Worker(再刷新一次生效)'); }); + } else { + navigator.serviceWorker + .register('/hornet_sw.js', { scope: '/', updateViaCache: 'none' }) + .then(function (Reg) { + console.log('[Hornet] Service Worker 就绪(作用域 ' + Reg.scope + '),unpacked 小文件将由单包命中'); + return Reg.update(); + }) + .catch(function (Err) { + console.warn('[Hornet] Service Worker 注册失败: ' + (Err && Err.message)); + }); + } } return __webpack_exports__; diff --git a/tools/split.js b/tools/split.js index 82e5293..6f4bb43 100644 --- a/tools/split.js +++ b/tools/split.js @@ -365,15 +365,23 @@ var __webpack_modules__ = window.__modules__; // 作用域必须是 /:首页 / 发起的 /play/... 请求才会被接管(serve.js 放行 Service-Worker-Allowed) // 用途:把 unpacked 下的散装小文件用单包就地命中(hornet_sw.js 内置单包缓存) if ('serviceWorker' in navigator && /^(localhost|127\\.0\\.0\\.1|\\[::1\\])$/.test(location.hostname)) { - navigator.serviceWorker - .register('/hornet_sw.js', { scope: '/', updateViaCache: 'none' }) - .then(function (Reg) { - console.log('[Hornet] Service Worker 就绪(作用域 ' + Reg.scope + '),unpacked 小文件将由单包命中'); - return Reg.update(); - }) - .catch(function (Err) { - console.warn('[Hornet] Service Worker 注册失败: ' + (Err && Err.message)); + if (/#nosw/.test(location.hash)) { + // #nosw:注销已注册的 Service Worker(清除单包缓存接管),用于排查镜像页问题;生效需再刷新一次 + navigator.serviceWorker.getRegistrations().then(function (Regs) { + Regs.forEach(function (Reg) { Reg.unregister(); }); + console.warn('[Hornet] #nosw:已注销 Service Worker(再刷新一次生效)'); }); + } else { + navigator.serviceWorker + .register('/hornet_sw.js', { scope: '/', updateViaCache: 'none' }) + .then(function (Reg) { + console.log('[Hornet] Service Worker 就绪(作用域 ' + Reg.scope + '),unpacked 小文件将由单包命中'); + return Reg.update(); + }) + .catch(function (Err) { + console.warn('[Hornet] Service Worker 注册失败: ' + (Err && Err.message)); + }); + } } `