CORS(跨站资源共享)介绍
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CORS(跨站资源共享)介绍相关的知识,希望对你有一定的参考价值。
起因
有同学在nginx站点配置中加了一行Access-Control-Allow-Origin *
,导致微信中业务数据异常,抓包看http头有两个Access-Control-Allow-Origin字段,一个是站点自己的域名,一个是*。
为了实现跨域资源访问,在代码和nginx配置中都加了Access-Control-Allow-Origin字段,但是浏览器有个原则,如果有两个Access-Control-Allow-Origin字段,那么都失效,哪个都不信。最终导致了微信中打开异常。
也引出了CORS。
定义和原理
什么是CORS跨站资源共享?
跨站源资源共享(CORS)是一份浏览器技术的规范,提供了 Web 服务从不同网域传来沙盒脚本的方法,以避开浏览器的同源策略[1],是 JSONP 模式的现代版。与 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。用 CORS 可以让网页设计师用一般的 XMLHttpRequest,这种方式的错误处理比 JSONP 要来的好。另一方面,JSONP 可以在不支持 CORS 的老旧浏览器上运作。现代的浏览器都支持 CORS[2]。
简单说,就是为了实现跨站访问资源的遍历,同时保护浏览器使用者的安全,提出的一种规范。如何保护的安全,在下一结做介绍。
在html中的图片、css、js等静态引用,和ajax发起的动态请求,都受同源策略影响。如果有跨域,都可以用CORS来实现(也有其他方法,CORS是标准)。
跨域请求主要用于:
- 调用XMLHttpRequest或fetchAPI通过跨站点方式访问资源
- 网络字体,例如Bootstrap(通过CSS使用@font-face 跨域调用字体)
- 通过canvas标签,绘制图表和视频。
意义
CORS怎么保护安全
客户端
保护用户访问网站的安全。防止用户在A站登录授权后,在访问恶意网站B时,B站在ajax中请求A站,获取A站的信息。
服务端
保护服务器的静态资源、接口数据等,都被自己信任的域名访问,不被其他未授权的网站拉走数据。
实现
客户端
在header中带上Origin字段,标明是跨域请求。如果需要发送带凭证的数据(cookie、Http认证和客户端SSL证明等),将WithCredentials设为true。
xhr.withCredentials = true;
如果请求服务器是非简单请求,浏览器会发出一个OPTION请求,和服务器协商信息。
服务器
服务器处理流程:
1 http头部是否有origin字段
2 没有,当成普通请求处理。
3 有,是否method是OPTIONS(preflight)
4 不是OPTIONS(简单请求),返Allow-Origin、Allow-Credentials等,并返回正常内容。
5 是,返回Allow-Headers、Allow-Methods等,内容为空。
nginx参考配置
add_header 'Access-Control-Allow-Origin' 'xxxx';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PUT, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Accept, Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'xxxx';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PUT, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Accept, Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
注意
1、在代码或nginx一个地方修改,不要在一个http头中有多个Access-Control-Allow-Origin字段,否则会触发“起因”中的问题。
2、修改配置最好在nginx配置中修改,其次在代码中修改,但是一定不要两侧都改,容易造成两侧混乱不容易维护。
3、业务站点不要为了省事给Access-Control-Allow-Origin设置为*,权限太开会有安全隐患。
4、按规范实现的浏览器,会做拦截。如果没有填写Access-Control字段或填写错误,即使服务端返回了全部数据,浏览器也会拦截不给页面。
参考
以上是关于CORS(跨站资源共享)介绍的主要内容,如果未能解决你的问题,请参考以下文章