资讯动态

Actual Budget 的 SharedArrayBuffer 运行前置条件全解析:HTTPS、COOP/COEP 响应头与浏览器兼容性

发布时间:2026/9/12 18:11:16 来源:尧图企业网站定制
Actual Budget 的 SharedArrayBuffer 运行前置条件全解析HTTPS、COOP/COEP 响应头与浏览器兼容性【免费下载链接】actualA local-first personal finance app项目地址: https://gitcode.com/GitHub_Trending/ac/actual本篇技术指南围绕 Actual Budget一个 local-first 的个人财务管理应用对 Web 平台特性SharedArrayBuffer的硬性依赖展开系统梳理该特性在现代浏览器中被默认禁用、需要满足哪些条件才能解锁的完整链路并结合本仓库源码逐一印证HTTPS 安全上下文、Cross-Origin-Embedder-Policy: require-corp与Cross-Origin-Opener-Policy: same-origin响应头以及受支持的浏览器版本。读完本文你将能够判断自己的部署环境是否满足 Actual 的运行前提并掌握在自建服务器、反向代理与开发环境中正确配置这些条件的具体方法。为什么 Actual 必须依赖 SharedArrayBufferActual 的前端desktop-client在浏览器中直接运行一个由 WebAssembly 编译的 SQLite 引擎sql.js用于本地读写预算数据库。这一路径依赖SharedArrayBuffer提供的跨线程共享内存能力。然而由于现代 CPU 的侧信道安全漏洞如 Spectre/Meltdown主流浏览器默认禁用了SharedArrayBuffer及相关特性只有当页面满足「跨源隔离cross-origin isolation」条件时才会重新启用。因此如果服务器不满足这些条件Actual 将无法运行——这不是可选优化而是硬性启动前提。从源码可以印证这一点。在 packages/loot-core/src/platform/server/sqlite/index.ts#L210-L214 的数据库打开逻辑中代码显式检查了typeof SharedArrayBuffer undefined并在缺失时走一条降级回退路径readIfFallbackif (typeof SharedArrayBuffer undefined) { const stream SQL.FS.open(SQL.FS.readlink(path), a); await stream.node.contents.readIfFallback(); SQL.FS.close(stream); }也就是说虽然代码为不支持的环境预留了回退分支但该分支只是尽力读取无法提供完整、可靠的功能。前端侧也有对应的用户提示packages/desktop-client/src/components/SharedArrayBufferWarning.tsx 会在typeof SharedArrayBuffer undefined时渲染一个警告链接提示「Your environment does not support SharedArrayBuffer. You may experience data loss or degraded functionality」你的环境不支持 SharedArrayBuffer可能遭遇数据丢失或功能降级。综合来看要让 Actual 完整运行需要同时满足以下三个条件HTTPS 安全上下文服务必须通过 HTTPS 提供COOP/COEP 响应头服务端必须返回Cross-Origin-Embedder-Policy: require-corp与Cross-Origin-Opener-Policy: same-origin受支持的浏览器访问端浏览器必须实现SharedArrayBuffer。下面逐一展开。条件一HTTPS——跨源隔离的安全上下文前提SharedArrayBuffer只能在「安全上下文secure context」中使用因此 Actual 必须通过 HTTPS 提供服务。如果使用云厂商托管通常已自动为你配置好 HTTPS如果自建服务器则需要自行启用。完整的启用指南见 Activating HTTPS这里提炼其关键路径。什么时候可以跳过 HTTPS 配置如果你在自己电脑上运行服务器且只通过localhost访问则无需配置localhost 本身被视为安全上下文同理云厂商已代管 HTTPS 时也无需重复配置。方案一config.json配置证书。在运行 Actual Sync Server 的目录下创建config.json若从源码构建位于packages/sync-server/若使用 Docker 容器则是容器内的/data目录即宿主机挂载卷的对应位置{ https: { key: /data/selfhost.key, cert: /data/selfhost.crt } }证书的获取方式可以是自签名用 OpenSSL 一条命令生成openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout selfhost.key -out selfhost.crt或用 mkcert 自动化也可以是借助 Tailscale、Caddy 等工具在不暴露公网的情况下获得受信任的合法证书。方案二环境变量配置证书。不方便创建文件时可将.key与.crt文件内容分别写入ACTUAL_HTTPS_KEY和ACTUAL_HTTPS_CERT两个环境变量若环境变量无法包含换行符可用\n代替Actual 会自动还原为换行。从源码看packages/sync-server/src/app.ts#L180-L185 的parseHTTPSConfig正是通过判断值是否以-----BEGIN开头来区分「直接传入的 PEM 内容」与「文件路径」随后在run()中据此创建 HTTPS 服务器app.ts#L219-L228。桌面应用场景在Wheres the server?界面输入服务器 URL 后若提示选择证书指定相应证书即可若证书由 mkcert 生成应指定根 CA 证书mkcert -CAROOT找到目录下的rootCA.pem而非服务器自身使用的证书。配置完成后务必以https://前缀重新访问实例并建议新开标签页而不是刷新报错页面。条件二COOP/COEP 响应头——解锁 SharedArrayBuffer 的关键仅 HTTPS 还不够。浏览器要求页面实现「跨源隔离」具体表现为两个响应头必须同时满足响应头必需取值作用Cross-Origin-Embedder-PolicyCOEPrequire-corp要求页面加载的所有资源显式允许跨源共享防止未授权的跨源资源进入进程Cross-Origin-Opener-PolicyCOOPsame-origin保证打开的窗口与顶层文档同源隔离跨源窗口的引用关系只要其中一个缺失或取值不符SharedArrayBuffer就会被禁用。需要特别强调的是如果使用官方默认的actual-server包作为服务器你无需关心这两个头——它们会被始终自动设置。下面的源码证据可以帮你确认这一点。actual-server始终自动注入 COOP/COEP在 packages/sync-server/src/app.ts#L150-L155 中Express 应用通过一个全局中间件为每个响应设置安全头其中就包含 COOP/COEP并顺带注入了 CSPapp.use((req, res, next) { res.set(Cross-Origin-Opener-Policy, same-origin); res.set(Cross-Origin-Embedder-Policy, require-corp); res.set(Content-Security-Policy, csp); next(); });部署在 Netlify 等静态平台_headers文件在 packages/desktop-client/public/_headers 中可以看到为静态托管准备的等效头配置同时还为 WebAssembly 资源补充了正确的 MIME 类型Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp Content-Security-Policy: default-src self blob:; img-src self blob: data:; script-src self unsafe-eval blob:; style-src self unsafe-inline; font-src self data:; connect-src http: https:; /*.wasm Content-Type: application/wasm本地开发Vite 开发服务器同样注入开发调试时这些头也不能缺席。在 packages/desktop-client/vite.config.mts#L242-L245 中Vite 配置了devHeadersconst devHeaders { Cross-Origin-Opener-Policy: same-origin, Cross-Origin-Embedder-Policy: require-corp, };此外packages/desktop-client/bin/serve-build.mjs#L39-L43 提供了一个用于 CI e2e 的最小静态文件服务器同样在每个响应上设置 COOP/COEP外加Cross-Origin-Resource-Policy: same-origin并注释说明这是「SharedArrayBuffer/SQLite 运行所需的头」。自建其他服务器 / 反向代理手动补齐并防止头重复如果你没有使用actual-server而是自己编写服务器或在前方架设反向代理就必须手动保证这两个头正确返回。此时最容易踩的坑是响应头重复Actual 应用本身已经尝试自动设置这些头若反向代理例如 NGINX又添加一遍浏览器会收到require-corp, require-corp这样的重复值从而判定安全策略非法并触发SharedArrayBufferMissing致命错误。Using a Reverse Proxy 文档专门记录了这一「header collision」问题并给出 NGINX 的正确做法用proxy_hide_header隐藏上游头再由代理作为唯一来源显式设置location / { proxy_pass http://actual_server:5006; # 防止上游与代理之间的头重复 proxy_hide_header Cross-Origin-Embedder-Policy; proxy_hide_header Cross-Origin-Opener-Policy; # 显式设置强制安全头 add_header Cross-Origin-Embedder-Policy require-corp always; add_header Cross-Origin-Opener-Policy same-origin always; add_header Origin-Agent-Cluster ?1 always; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }该文档还提供了 Caddy、Traefik、Apache httpd、ngrok 等常用反向代理的完整示例配置均以budget.example.org域名为例可直接作为参考模板。需要注意的是如果采用 NGINX 手动添加头的做法务必确认上游actual-server 或你的服务器没有同时下发这两个头否则仍会因重复而失效。条件三受支持的浏览器最后一个前提在客户端访问 Actual 的浏览器必须支持SharedArrayBuffer。Chrome、Firefox、Safari、Edge 的近现代版本均支持该特性但各浏览器启用「跨源隔离 SharedArrayBuffer」的版本节点并不一致详细的版本支持矩阵可参考 caniuse.com 的 SharedArrayBuffer 页面。对于不支持的环境Actual 前端会显示前文提到的警告提示SharedArrayBufferWarning.tsx点击后跳转到官方 troubleshooting 页面。另外FatalError.tsx 与对应的测试 FatalError.test.tsx 中处理了SharedArrayBufferMissing类型的致命错误这意味着当跨源隔离条件不满足时应用可能直接进入致命错误页而不是仅仅显示警告。如何验证自己的部署是否满足条件完成配置后建议按以下步骤自检确认以 HTTPS 访问地址栏应为https://自签名证书场景需先手动信任证书。检查响应头在浏览器开发者工具Network 面板中查看主文档响应确认Cross-Origin-Embedder-Policy: require-corp与Cross-Origin-Opener-Policy: same-origin均存在且取值正确且没有出现重复值。检查跨源隔离状态在控制台执行crossOriginIsolated若返回true则表示跨源隔离已生效SharedArrayBuffer可用。确认浏览器版本若使用的是较旧或小众浏览器参考 caniuse 的兼容性矩阵确认版本支持情况。如果问题依旧可进一步查阅 server troubleshooting服务器侧常见问题与 edge-browser.mdMicrosoft Edge 相关说明。总体原则是优先使用官方actual-server部署头自动注入无需干预若自建服务器或使用反向代理则必须自行补齐 HTTPS 与 COOP/COEP并避免响应头重复——三者齐备Actual 才能在你自己的基础设施上稳定运行。【免费下载链接】actualA local-first personal finance app项目地址: https://gitcode.com/GitHub_Trending/ac/actual创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价