浏览器 PNA 策略导致的 WebSocket 连接失败

8 阅读2分钟

浏览器 PNA 策略导致的 WebSocket 连接失败(纯客户端配置方案)

问题定性

这是 Chrome/Edge 自 Chrome 96+ ​ 起逐步强化的 Private Network Access (PNA) ​ 安全策略导致的问题。当公网页面(http://xxx.bogerj.com)尝试通过 JavaScript 访问本地环回地址(ws://127.0.0.1)时,浏览器会强制拦截,即使服务端正常运行。

故障表现

  • 前端控制台:连接失败,通常伴随 ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS或静默断开(错误码 1006)。
  • 服务端:Fleck 等服务端显示连接建立后立即收到 0 bytes read并关闭,因为浏览器根本没有发送握手包。
  • 工具差异:wscat、Postman 等非浏览器工具连接正常,因为它们不受 PNA 策略约束。

浏览器配置解决方案(仅限本地开发机)

方案 A:全局关闭检查(最常用)

适用于开发者本机快速调试,直接禁用安全拦截。

Chrome 操作:

  1. 地址栏输入 chrome://flags/#local-network-access-check
  2. Local Network Access Checks​ 选项改为 Disabled
  3. 点击 Relaunch​ 重启浏览器

Edge 操作:

  1. 地址栏输入 edge://flags/#local-network-access-check
  2. Local Network Access Checks​ 选项改为 Disabled
  3. 点击 重启​ 按钮

⚠️ 风险提示:此操作会降低浏览器对恶意网站探测内网服务的防护,严禁在生产环境或用户电脑上使用此方案


方案 B:单站点授权(更安全)

不关闭全局策略,仅允许特定网站访问本地网络。

  1. 保持 chrome://flags中的选项为默认值。

  2. 访问你的页面 http://xxx.bogerj.com:8083

  3. 尝试触发 WebSocket 连接。

  4. 观察浏览器地址栏左侧(锁形图标或信息图标旁):

    • 若有弹窗:点击“允许该网站访问本地网络设备”。
    • 若错过弹窗:点击地址栏左侧图标 → 网站设置​ → 找到 本地网络访问权限​ → 改为 允许

方案 C:启动参数(备用)

如果无法修改 Flags(如企业策略锁定),可在浏览器启动时添加参数。

Windows 快捷方式修改:

--unsafely-treat-insecure-origin-as-secure="http://xxx.bogerj.com:8083"

此参数告知浏览器将该 HTTP 源视为安全源,从而绕过部分 PNA 限制。

方案局限性说明

  • 仅限本机生效:上述所有配置只对你当前这台电脑的浏览器有效
  • 无法解决用户问题:你无法要求你的公网用户去修改他们的 Chrome Flags 或启动参数。对于正式交付给用户的场景,必须使用 Nginx 反向代理等服务器端方案(此处按你要求省略)。