浏览器 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 操作:
- 地址栏输入
chrome://flags/#local-network-access-check - 将 Local Network Access Checks 选项改为
Disabled - 点击 Relaunch 重启浏览器
Edge 操作:
- 地址栏输入
edge://flags/#local-network-access-check - 将 Local Network Access Checks 选项改为
Disabled - 点击 重启 按钮
⚠️ 风险提示:此操作会降低浏览器对恶意网站探测内网服务的防护,严禁在生产环境或用户电脑上使用此方案。
方案 B:单站点授权(更安全)
不关闭全局策略,仅允许特定网站访问本地网络。
-
保持
chrome://flags中的选项为默认值。 -
访问你的页面
http://xxx.bogerj.com:8083。 -
尝试触发 WebSocket 连接。
-
观察浏览器地址栏左侧(锁形图标或信息图标旁):
- 若有弹窗:点击“允许该网站访问本地网络设备”。
- 若错过弹窗:点击地址栏左侧图标 → 网站设置 → 找到 本地网络访问权限 → 改为 允许。
方案 C:启动参数(备用)
如果无法修改 Flags(如企业策略锁定),可在浏览器启动时添加参数。
Windows 快捷方式修改:
--unsafely-treat-insecure-origin-as-secure="http://xxx.bogerj.com:8083"
此参数告知浏览器将该 HTTP 源视为安全源,从而绕过部分 PNA 限制。
方案局限性说明
- 仅限本机生效:上述所有配置只对你当前这台电脑的浏览器有效。
- 无法解决用户问题:你无法要求你的公网用户去修改他们的 Chrome Flags 或启动参数。对于正式交付给用户的场景,必须使用 Nginx 反向代理等服务器端方案(此处按你要求省略)。