1.简介:CORS是“跨域资源共享”,它允许浏览器向跨域服务器发出XMLHttpRequest清求,从而克服了AJAX只能同源的使用限制。
2.支持问题:所有浏览器都支持该功能,IE浏览器不能低于IE10。
3.整个CORS通信过程都是浏览器自动完成,不需要用户参与,所有对开发者来说和同源的AJAX并没有什么区别,浏览器一旦发现是跨域的AJAX清求,就会自动附加一些头部信息,有时还会多出一次附加清求。因此实现CORS的重点就是在服务器,只要服务器实现了CORS接口,就可以实现跨域通信。
4.分为两种请求:简单清求和非简单请求
满足以下条件就是简单清求,不满足就不是简单清求。
- 请求方法是以下三种方法之一:
HEAD
GET
POST
(2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
A:简单请求
对于一个简单的清求,浏览器直接发出CORS清求,并且在头信息中加入一个Origin字段,值为请求源(包括协议,域名,端口号),服务器根据这个来判断是否接受这次清求。服务器接到这个请求后,如果不在许可范围之内,返回一个正常的HTTP回应,但是回应中不包含(Access-control-Allow-origin)字段,浏览器收到这个回应后,就会触发相应的onerror函数。注意:这种错误是无法通过状态码来区分的,因为服务器可能会返回200,如果origin指定的域名在许可范围内,服务器会在返回的头信息中添加一些字段,这些字段都是以(Access-Control)开头的字段
(1)Access-Control-Allow-Origin
该字段是必须的,就是清求时的Origin字段的值,要么就是一个*表示接受任意域名的请求。
(2)Access-Control-Allow-Credentials
该字段是可选的,表示是否发送Cookie,默认情况下,CORS清求是不发送cookie的,如果设置为true,那么服务器明确表示许可发送cookie,如果服务器不让浏览器发送cookie,那么删除这个字段就可以了。
(3)Access-Control-Expose-Headers
该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。上面的例子指定,getResponseHeader(‘FooBar’)可以返回FooBar字段的值。
刚才说到浏览器默认不发送cookie和HTTP认证信息,如果要把Cookie发送到服务器,一方面要服务器同意,并且制定Access-Contral-Allow-Credentials字段。
另一方面,需要开发者,在AJAX清求中打开withCredentials属性。否则就算浏览器同一发送cookie,浏览器也不会处理。
有的浏览器会自动发送Cookie,这个时候可以显式的声明withCredentials属性为false
需要注意的是:如果发送cookie那么Access-Control-Allow-Origin就不能设置为*,需要设置和与清求网页一致的域名,同时cookie也会遵循同源政策,只有用服务器域名设置的Cookie才会上传。
B:非简单请求
不满足简单清求的请求就是非简单清求,非简单清求,会有一个预检测清求。
如果浏览器发现此次清求不是简单清求,那么,浏览器就会发出一个预检测请求,此时浏览器的头头信息里会有Origin字段,表示清求来自那个源,还有
Access-Control-Request-Method字段,这个字段表示,清求的方法,
Access-Control-Request-Headers字段,这个字段表示,清求的额外信息。
服务器接收到以后,检车Oigin和字段是否在白名单中,如果在,就允许跨域清求,在返回的字段中,添加Access-Control-Allow-Origin和Access-Control-Allow-Mehods和Access-Control-Allow-Headers还有Access-Control-Allow-Credentials和Access-Control-Max-Age。
其中Access-Control-Max-Age为有效时间。在这个字段指定为时间范围内,浏览器再次跨域请求不需要在发出预检清求。
以后的清求都是简单清求。
6.与Jsonp的比较
CORS和JSONP的目的一样,但是CORS更为强大。JSONP只支持GET清求,CORS清求支持所有类型的HTTP清求,JSONP清求的优质在于支持老式的浏览器,以及可以向不支持CORS的网站清求数据。