在处理Web请求时偶尔会遇到 CORS 限制,比如页面数据异常时通过浏览器F12 debug 发现有如下报错:
Access to fetch at 'http://10.20.99.26:5000/temperature'
from origin 'http://10.20.99.26' has been
blocked by CORS policy: No 'Access-Control-Allow-Origin'
header is present on the requested resource.
If an opaque response serves your needs,
set the request's mode to 'no-cors' to
fetch the resource with CORS disabled.
CORS 报错的部分为:
以上报错信息来自使用 python flask 搭建的“获取 CPU 温度”的监控页面。CPU 数据从 Open Hardware Monitor 中获取。
Open Hardware Monitor 会启动一个 web 接口服务提供 CPU 传感器参数,访问该接口服务会得到含传感器参数的 JSON 字符串:
而Python Flask应用要做的就是将这些数据取出来,处理后再通过接口的形式吐出来:
最终在html页面中获取这些数据并显示出来,上面第一张截图是被 CORS 策略阻止后的 debug 报错。放行 CORS 后页面抓取数据正常:
回到正题,什么是 CORS ?
CORS是“跨域资源共享”的意思(CORS, Cross-Origin Resource Sharing)。这里涉及到一个概念:跨域请求(Cross-Origin Request)。
跨域请求(Cross-Origin Request)是指从一个域名的网页对另一个域名的资源发起的请求。在上面的例子里就是:
用户访问:10.20.99.26:80 => 10.20.99.26:5000
10.20.99.26:5000 => 10.20.99.26:8085
这里没有跨域,但实际上访问的同一台主机的不同端口,也相当于跨域。跨域请求会被浏览器限制,目的是为了保护用户的数据不被恶意网站窃取。
比如你访问 A 网站,结果 A 网站在用户不知情的情况下,偷偷向其他网站发起了请求。
跨域请求限制是一种安全策略,称为同源策略(Same-Origin Policy),同源策略要求以下三个条件必须一致,才允许访问资源:
-
协议(如 http 和 https)
-
域名(如 example.com)
-
端口(如 :80、:8080)
如果上述条件之一不同,那么就是跨域请求,通常会被浏览器拦截,除非目标服务器允许。
而 CORS 的引入就是为了解决跨域请求限制,因为大多少服务都没法保证同源策略。很多网页应用都是由不同端口、不同域名的服务一起组合起来提供服务的。
解决 CORS 要从服务端入手,对于当前的例子只需要在 python 代码中加入如下行即可:
对于 nginx 服务则需要配置 nginx.conf :
events {
worker_connections 1024;
}
http {
server {
listen 80;
server_name example.com;
location / {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
}
}
}
其中 Access-Control-Allow-Origin: * 表示允许所有来源访问资源。
add_header 'Access-Control-Allow-Origin' '*';
一般从事Web接口服务开发会遇到CORS限制,如果Web数据出不来可以通过浏览器的F12调试工具查一查,如果有 Access-Control-Allow-Origin 字眼儿基本上就可以定位为CORS限制。可以要求接口服务提供方调整CORS策略。
最后插个题外话,自己写页面监控CPU温度效率太低了。使用 aida64 副屏方案效率更高,秀一下我的成果:
全文完。
原文始发于微信公众号(生有可恋):什么是 CORS
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论