配了五年 WebSocket,每次连本地服务都要绕过混合内容限制——今天 Chrome 154 用一个 options bag 把这件事彻底原生化了

写过 WebSocket 的人都踩过这个坑:线上页面想连个本地开发机上的 ws 服务,浏览器直接报 mixed content 错误——HTTPS 页面不允许明文 ws 连接,哪怕目标其实是同一个笔记本上的进程。以前要么让用户装插件,要么让本地服务配 HTTPS,要么靠代理绕路。

今天 Chrome 154 用一个 constructor options 把这件事彻底原生化了。

Before:绕 mixed content 三件套

以前写这样一个内缩下划线,需要伪元素配合 background 渐变来模拟:

// 以前:本地 WebSocket 连不上 HTTPS 页面
const socket = new WebSocket('ws://localhost:8765/chat');
// Error: Mixed Content: The page at 'https://app.example.com'
// was loaded over HTTPS, but attempted to communicate
// with WebSocket at 'ws://localhost:8765/chat'.

// 绕路方案 A:代理(运维成本高)
const socket = new WebSocket('wss://proxy.example.com/chat');
// 绕路方案 B:让用户装浏览器插件关闭 mixed content
// 绕路方案 C:本地也配一套 HTTPS(证书维护成本更高)

After:targetAddressSpace 选项

// Chrome 154+:用 targetAddressSpace 声明目标是 local 网络
const socket = new WebSocket('ws://local-server.example/chat', {
  targetAddressSpace: 'local'
});

targetAddressSpace 有三个取值:

  • 'public':默认,公开网络目标
  • 'local':本地网络(如 192.168.x.x、.local 域名)
  • 'loopback':本机回环(如 localhost、127.0.0.1)

当 HTTPS 页面用 'local' 或 'loopback' 时,浏览器会触发 Local Network Access 权限提示,用户同意后即可通信,不再被 mixed content 规则拦截。

配套:WebSocketInit options bag

Chrome 154 还引入了 WebSocket constructor 的 options bag 形式,作为 future-proof 的扩展点:

// 原来(仍有效,但 options bag 是扩展方向)
const socket1 = new WebSocket('wss://example.com/chat', 'soap');

// Chrome 154+:统一 options bag 写法
const socket2 = new WebSocket('wss://example.com/chat', {
  protocols: ['v2.chat', 'v3.chat']
});
const socket3 = new WebSocket('ws://local-dev.example/chat', {
  targetAddressSpace: 'local'
});

落地检查清单

1. 浏览器兼容性: Chrome 154+ 稳定,Firefox/Safari 暂未实现。用 feature detection 保护:

if ('WebSocket' in window) {
  // 检测是否支持 options bag 形式
  try {
    const testSocket = new WebSocket('wss://example.com', { protocols: [] });
    testSocket.close();
  } catch (e) {
    // 不支持 options bag,回退到字符串协议形式
  }
}

2. 权限提示处理: 用户会看到系统权限提示,提前在 UI 上说明原因

3. hostname 要求: 目标 hostname 必须解析到本地 IP,否则连接被阻断

4. Fallback 方案: 不支持的浏览器仍走代理或 HTTPS 方案

下一步

把项目里连本地 WebSocket 服务的代码搜出来,检查是否用了代理或插件绕路。Chrome 154+ 可以直接用 targetAddressSpace: 'local' 替代,同时保留兼容性检测。


来源:Chrome 154 Release Notes(developer.chrome.com,2026-09-22) + WHATWG WebSocket spec PR #76 + WICG Local Network Access explainer

评论区

0 条评论

登录后可评论。