首先我们有一个概念,那就是“同源准则",也就是same-origin policy,它要求一个网站(协议+主机+端口号)来确定的脚本、XMLHttpRequest和Websocket无权去访问另一个网站的内容。
如果设置不正确,它通常会报错如下:No ‘Access-Control-Allow-Origin‘ header is present on the requested resource。
所谓CORS,也就是Cross-Origin Resource Sharing,它的基本原理是通过设置HTTP请求和返回中的header,告诉浏览器该请求是合法的。这就涉及到服务器和浏览器双方的设置:请求的发起(Http Request Header)和服务器对请求正确的响应(Http Response Header).
我们可以使用原生的javascript来通过XMLHttpRequest或者XDomainRequest来发起请求,我们也可以通过jQuery的$.ajax()来发起XHR或者CORS请求,不过该方法不支持IE下的XDomainRequest,我们需要另外的插件来解决这个问题。
其中通过jQuery调用的范例乳腺癌:
$.ajax({
type:‘GET‘,
url:‘http://www.aaa.com‘,
contentType:‘text/plain‘,
success:function(){},
error:function(){}
}});
根据请求的内容不同,浏览器会需要添加对应的Header或者发起额外的请求。其中的细节都由浏览器来处理,对于用户来将是透明的。
一般我们将CORS分为两类:(1)简单请求 (2)不是那么简单的请求
所谓简单请求,就是请求类型必须是GET、POST、HEAD三者中的一个,请求头Header中只能包含:Accept、Accept Language、Content Language、Last Event ID、Content Type,而且Content Type只接受application/x-www-form-urlencoded、multipart/form-data、text/plain这三种。
除了上面的条件,比如PUT、DELETE或者Content Type是application/json,均为"不是那么简单的请求".这种请求浏览器会在真实请求之前,额外发起一次类型为OPTIONS的请求(preflight request),只有服务器正确的响应了OPTIONS请求之后,浏览器才会发起该请求。
对于简单请求,下面是b.com向a.com发起的一次GET请求的范例:
GET /xin HTTP/1.1 Origin: http://b.com Host: a.com Accept-Language: en-US Connection: keep-alive User-Agent: Mozilla/5.0...
在响应之前,其中我们的头部应该这么设置,下面是一个范例:
Access-Control-Allow-Origin: http://b.com Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: FooBar Content-Type: text/html; charset=utf-8
其中Access-Control-Allow-Origin是Server同意跨域访问的域名列表,如果我们允许任意网站请求资源,此处可以填写"*",而Access-Control-Expose-Headers可以设置返回额Header以传递数据,简单请求中允许使用的Header包括:Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma。
对于不是那么简单的去年跪求,下面是一个范例:
OPTIONS /cors HTTP/1.1 Origin: http://b.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: X-Custom-Header Host: a.com Accept-Language: en-US Connection: keep-alive User-Agent: Mozilla/5.0...
其中Access-Control-Request-Method代表真实请求的类型,而Access-Control-Request-Headers则代表真实请求的请求头的key内容。服务器在验证了这两项内容的合法性之后才会同意浏览器发起真实的请求。
下面是对应的响应的头部设置:
Access-Control-Allow-Origin: http://b.com Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: X-Custom-Header Content-Type: text/html; charset=utf-8
还有一个就是Access-Control-Max-Age,它是浏览器保存的一个缓存的时间,单位是秒,在缓存过期之前,浏览器无须再次验证同一类型的请求是否合法。