CORS请求之非安全网站发起的专用网络请求
问题
自从谷歌浏览器升级到chrome94版本后,在非安全网站下通过请求本地接口就会出现以下错误: Access to XMLHttpRequest at 'http://127.0.0.1:10005/' from origin 'http://testing.hongyangcloud.com' has been blocked by CORS policy: The request client is not a secure context and the resource is in more-private address space local
.
排查
在被请求127.0.0.1的服务端添加有允许跨域访问的响应头 Access-Control-Allow-Origin:*,而且在内网IP网站下访问是没有问题的,那就不是浏览器的同源策略导致的。查了一下,chrome94开始禁止从非安全网站发起的专用网络请求。
Chrome 重大更新,将限制 localhost 访问
Chrome 正在计划禁止从非安全网站发起的专用网络请求,目的是保护用户免受针对专用网络上的路由器和其他设备的跨站点请求伪造 (CSRF ) 攻击:
- 从 Chrome 94 开始阻止来自不安全公共网站的私有网络请求。
- 在 Chrome 101 中结束的弃用试验。
- 在 Chrome 92 中引入一些 Chrome 策略,允许托管的 Chrome 部署永久绕过弃用。
这是chrome的更新日志:https://developer.chrome.com/blog/private-network-access-update/
啥是非安全网站?
在Chrome浏览器中,访问时会提示连接不安全,用户一点击网页中任何的表单打算输入信息的时候,浏览器地址栏这种灰色的“不安全”立即红色高亮显示“不安全”。
其实就是没有部署受信任CA签署的有效TLS证书的网站
啥是专用网络?
在互联网的地址架构中,专用网络是指遵守 RFC 1918(IPV4) 和 RFC 4193(IPV6) 规范,使用专用 IP 地址空间的网络。私有 IP 无法直接连接互联网,需要使用网络地址转换( Network Address Translator,NAT )或者代理服务器 ( proxy server )来实现。
一般,我们在企业里搭建的局域网、家庭网络里的局域网、你本地的 localhost ,都属于专用网络。
专用网络访问规范
专用网络访问规范 (以前称为 CORS-RFC1918)会限制网站向专用网络上的服务器发送请求的能力。它只允许来自安全上下文( HTTPS )的此类请求。该规范扩展了跨域资源共享 ( CORS ) 协议,因此网站现在必须要经过专用网络上的服务器授权会才能发送请求。
私有网络请求是其目标服务器的 IP 地址比获取请求发起者的 IP 地址更私有的请求。例如,从公共网站 ( https://example.com ) 到私有网站 ( http://router.local ) 的请求,或从私有网站到 localhost 的请求。
以下试验了几种环境下的访问情况:
我们在开发过程中,这几种情况都可能遇见的,所以需要开发者提前试用并作出应对。
访问 localhost
如果你的 HTTP 网站需要向 localhost 发出请求,那么你可以参考以下几种方案:
1. 屏蔽客户端设置
Chrome有个配置可以禁用这个功能,在Chrome地址栏输入“chrome://flags/
” 进入页面后,搜索“Block insecure private network requests
”,设置为Disabled,再Relaunch就好了:
请注意:chrome屏蔽不安全私有网络请求的设置从94版本到101版本下有效,Chrome 101 中结束的弃用该试验;到时候还是会被禁用,目前先以改方式解决。
2. 网站升级HTTPS
只需要将你的网站升级到 HTTPS 。混合内容不会阻止以 http://localhost (或 http://127...*、http://[::1] )为目标的请求,即使是从安全上下文发出的。
请注意,这里有个坑, WebKit 引擎和基于它的浏览器(比如 Safari )这里并没有遵循 W3C 混合内容规范,上面这些请求会作为混合内容并禁止访问。它们也没有实现专用网络访问,因此网站如果使用此类浏览器的客户端,需要试用 HTTP 协议,此类浏览器仍允许向 localhost 发出请求。
3. 不使用AJAX进行数据交互
简单访问方式可以采用JSONP,不过我考虑的是能不能使用websoket
待补充...