前端调用内部接口突然报 CORS 错误?这个浏览器安全机制很多人第一次遇到都不知道怎么查
你有没有遇到过这种事:本地开发好好的,前端页面调个 /api/internal/users 这样的内部接口,突然浏览器就给你一个 CORS 错误——「Private network access not allowed」。但这个接口明明就在你内网里,别人能调,你就不行。
这不是你代码写错了,是浏览器悄悄加了一道安全门。
Private Network Access CORS 是什么
Chrome 从版本 102 开始(2022年),对私有网络(private network)的请求做了强制 CORS 检查。简单说就是:公共网页不能随意访问你的局域网内部服务。
什么叫公共网页?线上域名、localhost 都算。即使你在公司内网,如果页面是通过 HTTPS 访问的,浏览器同样会拦截你调用 HTTP 内网接口。
这个机制是为了防一种攻击:恶意广告页在你不知不觉的情况下,悄悄扫描你的内网设备、读取路由器管理界面、甚至探测打印机地址。全程你看不见,浏览器在背后把门。
什么时候会触发
两种情况最常见:
第一种,你的页面在线上跑了(比如做了内网穿透),但调用的后端接口是内网地址。这种组合以前没问题,现在浏览器直接拦。
第二种,第三方嵌入脚本想调用你的内部 API。比如你在页面里嵌了一个监控 SDK,SDK 尝试从内网采集数据,这时候同样会被拦。Chrome 104 之后连这种情况也开始管了。
怎么判断是不是这个问题
打开 Chrome DevTools,看 Console 和 Network 两个地方。
Console 里会看到这种错误:
Access to internal resource at http://192.168.1.100:8080/api/data is blocked. The request is blocked because private network access is not allowed.
Network 面板里这条请求会显示状态是 CORS Error,响应头里会有 X-Firefox-Private-Network-Access-CORS-Blocked 或者 Chrome 的 ERR_BLOCKED_BY_PRIVATE_NETWORK_ACCESS 相关字样。
现在到底怎么解决
方案一:让后端加 CORS 响应头。最标准的做法是在后端返回里加:
Access-Control-Allow-Private-Network: true
这个响应头就是告诉浏览器「我知道这事,我允许内部网络访问」。后端加上这个头,浏览器就放行。
方案二:如果是本地开发环境,可以考虑在 Chrome 启动时加参数:
--disable-features=BlockPrivateNetworkAccess
但这个只适合本地调试,不要用在生产。
方案三:把内部服务暴露成公共地址,用统一的网关做转发。这样页面和接口走的是同一个网络环境,浏览器认为安全。
方案四:如果你控制不了后端(比如是老系统没人维护),可以考虑把接口调用迁移到服务端做,前端只调用自己域下的接口。
浏览器为什么要搞这一出
以前攻击者可以在页面里用 fetch 或 img 标签悄悄探测内网。路由器管理界面大多数默认没密码,读到的数据直接外传。这种攻击成本极低,防御却长期被忽视。
Private Network Access CORS 就是在浏览器层面补了这个洞。前端开发者可能第一次遇到会觉得莫名其妙,但这个机制确实保护的是你自己——如果你在内网环境访问了一个恶意页面,它现在没法再随便扫描你周围的设备了。
下一步你可以做什么
如果你维护的内部系统突然发现前端调不通了,先查后端能不能加那个响应头。如果后端是 Nginx,改一下配置加一行最多五分钟的事。
如果你是系统设计者,在规划前后端通信的时候,尽早考虑接口是走内网还是公网,这会影响后续的架构选择。
这个机制目前主流浏览器里 Chrome/Edge/Safari 都支持了,Firefox 也在推进。迟早大家都会遇到,早了解早好。
评论区
登录后可评论。