一、什么是CORS?
CORS(Cross-Origin Resource Sharing)是一种机制,它使用额外的HTTP头来告诉浏览器,让运行在一个origin (domain) 的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源在请求时,它使用一个GET、POST或是HEAD方法,然后这个资源响应一个HTTP头,表示允许特定的源来访问该资源,从而实现在不同域之间(协议、域名、端口号)进行安全地数据传输。
二、CORS的场景
CORS适用于XMLHttpRequest或Fetch API发出的请求,用于跨域访问其它域名下的数据,典型的场景有:
- Web前端应用程序发出跨域AJAX请求,比如一个设置在a.com域名下的Web应用请求b.com域名下的资源。
- CORS也适用于Web前端框架客户端应用程序与API客户端服务之间的跨域调用。
三、CORS的请求头和响应头
1、请求头:
Origin: http://a.com
2、响应头:
Access-Control-Allow-Origin: http://a.com Access-Control-Allow-Headers: *, Authorization Access-Control-Allow-Methods: * Access-Control-Allow-Credentials: true
四、CORS的错误码
1、简单请求时,出现以下情况会产生CORS错误码:
- 请求方式不是GET、HEAD、POST,如PUT、DELETE等。
- 请求头信息不是以下几种,参考HTTP规范中的“列出的首部字段”:
Accept Accept-Language Content-Language Last-Event-ID Content-Type(仅限于部分值)
2、复杂请求时,出现以下情况会产生CORS错误码:
- 请求方法并不是GET/POST/HEAD。
- 发送了POST请求,但不是以下类型之一:
application/x-www-form-urlencoded multipart/form-data text/plain
五、CORS错误的解决方法
CORS错误解决分两种情况:一种是服务端提供跨域支持,一种是在前端搭配后端提供跨域支持,该解决方法大体分为以下几种:
1、服务端提供跨域支持。
在服务器端添加 Access-Control-Allow-Origin头部,可允许特定的源访问该资源,并可在头部添加允许的 HTTP 方法和响应头域。
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { header("Access-Control-Allow-Origin: http://a.com"); header("Access-Control-Allow-Headers: *, Authorization"); header("Access-Control-Allow-Methods: *"); header('Access-Control-Allow-Credentials: true'); exit; } header("Access-Control-Allow-Origin: http://a.com"); header('Access-Control-Allow-Credentials: true');
2、前端搭配后端提供跨域支持。
在前端发起请求时,设置请求头:
const xhr = new XMLHttpRequest(); xhr.withCredentials = true; xhr.open('GET', 'http://b.com/api', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.setRequestHeader('Cookie', document.cookie) xhr.setRequestHeader('Authorization', auth); xhr.send();
在后端返回请求响应时,设置响应头:
header('Access-Control-Allow-Origin: http://a.com'); header('Access-Control-Allow-Headers: *, Authorization'); header('Access-Control-Allow-Methods: *'); header('Access-Control-Allow-Credentials: true'); echo $responseBody;
六、CORS错误码实际案例
1、ERR_TOO_MANY_REDIRECTS:重定向次数过多,通常是请求被拦截。
2、ERR_FAILED:通常是请求超时,或者是服务器内部错误。
3、ERR_TUNNEL_CONNECTION_FAILED:WebSocket服务请求失败。
4、ERR_ABORTED:用户主动中断请求。
5、ERR_CONNECTION_REFUSED:请求被服务器拒绝,通常是跨域问题导致。