SharedArrayBuffer 终于可以在浏览器中再次使用了,但前提是页面必须处于“跨源隔离”(cross-origin isolated)状态——这需要设置两个响应头。添加这些响应头迫使我删除了网站上的每一个第三方脚本,这一举动重塑了整个前端的构建方式以及数据泄露的情况。

为什么这些响应头至关重要

SharedArrayBuffer 实现了 JavaScript 的真正多线程,这是在标签页内运行 ffmpeg 的先决条件。在经历了 Spectre 风格的缓解措施后,现代浏览器重新启用了该功能,但将其与跨源隔离绑定在了一起。为了实现这种隔离,服务器必须发送:

  • Cross-Origin-Opener-Policy: same-origin
  • Cross-Origin-Embedder-Policy: require-corp

第二个响应头 require-corp 告诉浏览器,任何外部资源要么必须携带 Cross-Origin-Resource-Policy 响应头,要么必须通过 CORS(跨源资源共享)进行获取。大多数第三方服务并未设置这些响应头,因此它们的脚本、字体和 iframe 会被直接拦截。

开启隔离后丢失了什么

一旦响应头生效,一系列故障接踵而至:

  • 数据分析 (Analytics) – 大多数提供商使用简单的 <script> 加载其跟踪代码,这种方式发起的请求不带 CORS。如果没有 CORP 响应头,请求会被拒绝,导致跟踪器无法运行。
  • Google Fonts – 样式表是从 fonts.googleapis.com 获取的,且不带 CORS。浏览器会将其丢弃,导致页面失去自定义字体。
  • 嵌入式媒体 – YouTube iframe 和小部件脚本缺少 CORP,因此停止渲染。
  • OAuth 弹窗 – 由于严格的同源策略,window.opener 关系被破坏,导致通常基于弹窗的登录流程失效。

简而言之,除非该域名选择加入新的响应头机制,否则任何依赖第三方域名的资源都会消失。

在没有中间商的情况下重建

面对一个瘫痪的网站,我围绕自托管资源重写了前端技术栈:

  • 字体和图像 现在从我自己的源站提供,消除了对外部样式表的需求。
  • 数据 API 构建在由我控制的私有后端上,因此每个请求都保留在我的域名内。
  • 数据分析 变成了一个微小的 Cloudflare Worker,它接收 POST 事件并将其存储在私有存储桶中。客户端只需十几行 fetch 代码。
  • 错误报告和会话重放 工具(如 Sentry)被完全弃用;任何崩溃现在都会记录到我自己的端点。

如果仍需使用外部资源,唯一可行的路径是通过你拥有的服务器进行代理,在浏览器看到它之前添加必要的 CORP 响应头。

隐私收益与运维成本的权衡

直接的好处显而易见:网站不再向广告网络、字体提供商或视频平台泄露使用数据。所有遥测数据都由我控制,我可以随时删除它们。对于典型的第三方技术栈来说,这种程度的隐私保护很难实现。

代价是额外的维护负担。托管字体、处理分析数据存储以及保持代理程序更新,这些都是大多数开发者外包给专业服务的任务。这种方法也意味着会失去这些服务提供的功能——例如实时错误聚合或详细的漏斗可视化。

反方观点:生态系统会适应吗?

有人认为,第三方供应商最终会添加所需的响应头,从而使采用跨源隔离变得毫无痛苦。少数供应商已经这样做了,但大多数广泛使用的服务仍然没有。在生态系统赶上之前,开发者必须决定隐私收益是否超过了自托管所需的工程投入。

如何验证你是否真正实现了隔离

在开始重写之前,请确认浏览器认为你的页面已隔离:

crossOriginIsolated   // should be true
typeof SharedArrayBuffer   // should be "function"

如果其中任何一项检查失败,说明响应头未正确应用,SharedArrayBuffer 将仍然无法使用。

开发者下一步该做什么?

随着越来越多的 Web 应用寻求多线程 JavaScript 带来的性能提升,第三方供应商采用 CORP 的压力将会增加。与此同时,任何需要 SharedArrayBuffer 的项目都应规划自托管资源策略或轻量级代理层。密切关注浏览器发行说明中关于隔离要求的变化也将至关重要。

核心结论: 启用跨源隔离以解锁 SharedArrayBuffer 迫使人们做出一个艰难的选择——是保留第三方脚本带来的便利,还是为了实现更严密、自主可控的隐私模型而进行权衡。这一决策将重塑现代网站的技术架构和数据流足迹。