跨域CORS

跨域CORS

Cross-origin resource sharing
跨域资源共享
允许浏览器向跨源服务器发出 XMLHttpRequest请求 克服ajax只能同源请求的限制

跨域请求需要浏览器和服务器同时支持 目前浏览器都支持该功能,IE必须10以上

跨域请求被分为两种 简单请求和非简单请求
满足一下俩点的为简单请求
1.请求方法是HEAD GET POST请求三者
2.http的请求头信息不得超出以下字段
(1)Accept
(2)Accept-Language
(3)content-Language
(4)Last-Event-ID
(5)Content-Type: 只能是application/x-www-urlencoded、multipart/form-data、text/plain

只要满足上述的条件就是简单请求, 浏览器对简单请求和非简单清楚的处理方式是不同的

简单请求

简单请求浏览器会直接发出请求,在请求头信息中会增加Origin字段
Origin字段的作用是来说明 这次请求是来自哪个源(协议 + 域名 + 端口)即同源策略的三个内容。 服务器会根据请求的源信息来判断是否同意该请求

如果Origin制定的源不在服务器的允许的范围内 服务器会返回正常的http回应,但是浏览器看到请求回应的头信息中没有包涵Access-Control-Allow-Origin字段
就知道出错了,会抛出跨域请求失败的错误 会被XMLHttprequest 的 onerror 函数捕捉。
这种错误无法通过状态码识别,因为除了 403 还有可能会返回 200

如果Origin指定的域名在许可范围内,服务器返回的响应头中会有以下的信息
Access-Control-Allow-Origin: http://www.baidu.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8

三个字段都以Access-Control-开头

Access-Control-Allow-Origin
该字段的值要么是Origin制定的域名 要么是*

Access-Control-Allow-Credentials
该字段的值是一个布尔值,表示是否允许发送Cookie。默认情况下跨域请求是不携带cookie的 即默认值为false
如果值设置为true Cookie就可以包含在请求中,一起发给服务器。这个值只能设置为true,如果服务器不要浏览器发送cookie删除该字段即可

Access-Control-Expose-Headers
CORS请求时,getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。
如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。

如果跨域请求需要发送cookie 除了设置Access-Control-Allow-Origin的值为true,
还需要设置 withCredentials 的值为true。

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

有些浏览器会默认将withCredentials值设置为true,如果不想上传cookie那就将withCredentials设置为false就可以了。

非简单请求

非简单请求是有特殊要求的跨域请求,比如请求方式是put或者delete,或者Content-Type字段的值为 application/json 。
非简单的跨域请求在正式通信前会增加一次http查询请求,称为预检请求(preflight)。
浏览器会先询问服务器,当前网页所在的域名是否在服务器的许可名单中,以及可以使用那些HTTP动词和头信息。只有的到正确的答复,浏览器才会发出正式的XMLHttpRequest请求,否则就会报错。

预检请求的请求方式是OPTIONS,表示这个请求是用来询问的。

请求头里的关键字段

Origin:表示是来自哪里的请求
Access-Control-Request-Method: 必要字段,用来列出浏览器的跨域请求会用到那些HTTP方法。
Access-Control-Request-Headers: 该字段是一个逗号分隔的字符串,指定浏览器跨域请求会额外发送的字段信息。

预检请求的回应

Access-Control-Allow-Origin: 表示请求的来源
Access-Control-Allow-Methods: 表示服务器支持的所有跨域请求方法
Access-Control-Allow-Credentials: 该字段的值是一个布尔值,表示是否允许发送Cookie。默认情况下跨域请求是不携带cookie的 即默认值为false,如果值设置为true,Cookie就可以包含在请求中,一起发给服务器。这个值只能设置为true,如果服务器不要浏览器发送cookie删除该字段即可.
Access-Control-Max-Age: 选填字段,用来指定本次预检请求的有效期,单位为秒。设置后在这个时间范围内不用再发出另外一条预检请求。

一旦服务器通过了预检请求,往后的每次跨域请求就会和简单请求一样。

与JSONP的比较

CORS与JSONP的使用目的相同,都为解决跨域问题,但是比JSONP更强大。
JSONP只能支持get请求,CORS支持所有的Http请求。JSONP则具有更强的兼容性,以及可以向不支持CORS的网站请求数据

JSONP优缺点
1.它只支持GET请求而不支持POST等其它类型的HTTP请求
2.它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
3.jsonp在调用失败的时候不会返回各种HTTP状态码。

4.缺点是安全性。万一假如提供jsonp的服务存在页面注入漏洞,即它返回的javascript的内容被人控制的。那么结果是什么?所有调用这个 jsonp的网站都会存在漏洞。于是无法把危险控制在一个域名下…所以在使用jsonp的时候必须要保证使用的jsonp服务必须是安全可信的。

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2019-2021 伯温

请我喝杯咖啡吧~