简介
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。 因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
请求
1. 简单请求
- 浏览器在头信息里自动添加origin
- 如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段。
Access-Control-Allow-Origin: http://api.bob.com- (可以是* ,允许所有跨域)
Access-Control-Allow-Credentials: true- (是否可以发送cookie,不要就删除这个字段,默认cookie不包含在CORS请求中)
Access-Control-Expose-Headers: FooBar- (getResponseHeader 默认获取的6个字段不包含自定义头的,通过getResponseHeader('FooBar')获取)
Content-Type: text/html; charset=utf-8
withCredentials 属性- 服务端要同意:
Access-Control-Allow-Credentials: true - 开发者要在AJAX请求中打开这个属性:
xhr.withCredentials = true;
- 服务端要同意:
注意!!!: 如果要发送Cookie,Access-Control-Allow-Origin就不能设为*,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。
2. 非简单请求:多一次HTTP查询请求
要求:
- PUT
- DELETE
- content-type: application/json
会在通信前问下服务器,所在网页是否在服务器的许可名单内,通过了才能才出正式的XMLHttpRequest请求。
注意!!:如果服务器否定了"预检"请求,会返回一个正常的HTTP回应,但是没有任何CORS相关的头信息字段,浏览器会认定服务器不同意预检,从而抛出一个错误,被XMLHttpRequest的onerror回调函数捕获。注意,这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200。
预检请求的HTTP头信息
关键:
Origin: http://api.bob.com (发送的源)Access-Control-Request-Method: PUT (请求方法)Access-Control-Request-Headers: X-Custom-Header (自定义头信息)
OPTIONS /cors HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
预检请求的回应
关键:
Access-Control-Allow-Origin: * (允许所有跨域)
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Methods: GET, POST, PUT(表明服务器支持的所有跨域请求的方法)
Access-Control-Allow-Headers: X-Custom-Header
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
Access-Control-Max-Age: 1728000
//(用来指定本次预检请求的有效期,在此期间,不用发出另一条预检请求。)