修复发行游戏在沙箱中访问存储报错

将运行期存储兼容层保存为独立 JavaScript 文件,通过 include_str 注入发行 HTML。

保持 opaque sandbox 隔离,仅提供当前运行实例的 localStorage 与 sessionStorage 兼容能力。

同步发行沙箱验收脚本和玩法运行契约文档。
This commit is contained in:
2026-10-02 17:06:46 +08:00
parent 772e9f0d42
commit db344426f2
4 changed files with 87 additions and 10 deletions
@@ -7,8 +7,8 @@
// E2E_CHROMIUM_EXECUTABLE=<ms-playwright 里的 chrome.exe,可省略>
// E2E_ADMIN_USER=... E2E_ADMIN_PASSWORD=... npm run check:game-distribution-sandbox-e2e
//
// 覆盖:ES module 与同包资源能在 opaque sandbox 下载入;外站 fetch / WebSocket 被挡;
// localStorage / document.cookie / 父文档 DOM 都拿不到;顶层跳转与弹窗被挡;
// 覆盖:ES module 与同包资源能在 opaque sandbox 下载入;运行期 storage 兼容层可用;
// 外站 fetch / WebSocket 被挡;document.cookie / 父文档 DOM 都拿不到;顶层跳转和弹窗被挡;
// 敏感权限(定位)被拒;同时核对发行网关的 CSP / nosniff / CORS / Cookie 403 策略。
import { createRequire } from 'node:module';
import path from 'node:path';
@@ -140,14 +140,14 @@ const PROBE_APP = `import { marker } from './helper.js';
const results = { moduleLoaded: marker === 'helper-ok' };
// 探针自身也可能被浏览器直接抛错挡下(例如 opaque origin 读 cookie),
// 所以每一步单独兜底,最后无论如何都把结果 postMessage 给父页面。
try {
// opaque origin 的原生 storage 不可用,但发行网关会在游戏脚本前注入运行期兼容层。
try {
window.localStorage.getItem('probe');
results.storageBlocked = false;
window.localStorage.setItem('probe', 'ok');
results.storageAvailable = window.localStorage.getItem('probe') === 'ok';
window.localStorage.removeItem('probe');
} catch {
results.storageBlocked = true;
results.storageAvailable = false;
}
try {
@@ -479,8 +479,8 @@ document.body.appendChild(frame);
results.moduleLoaded === true,
);
check(
'localStorage 在 opaque sandbox 下不可用',
results.storageBlocked === true,
'opaque sandbox 下运行期 storage 兼容层可用',
results.storageAvailable === true,
);
check(
'document.cookie 在 opaque sandbox 下为空',