前端跨域之CORS详解

CORS:跨源资源分享Cross-Origin Resource Sharing。

它是W3C标准,是跨源AJAX请求的根本解决方法。相比JSONP只能发GET请求,CORS允许任何类型的请求。CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

跨域分为2种请求:简单请求和预检请求(非简单请求)

简单请求

(1) 请求方法是以下三种方法之一: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

对于简单请求,浏览器会直接发送CORS请求,具体说来就是在header中加入origin请求头字段。同样,在响应头中,返回服务器设置的相关CORS头部字段,Access-Control-Allow-Origin字段为允许跨域请求的源。请求时浏览器在请求头的Origin中说明请求的源,服务器收到后发现允许该源跨域请求,则会成功返回,具体如下:

预检请求 

预检请求发生在实际请求之前,用于检查服务器是否支持 CORS,以判断实际请求发送是否安全。预检请求使用的方式是 options。如果发现服务器支持该请求,则会将真正的请求发送到后端,反之,如果浏览器发现服务端并不支持该请求,则会在控制台抛出错误 

当一个请求不是“简单请求”时,即应该先发送预检请求,比如:

(1)请求方式不是GETHEADPOST

(2)请求设置了自定义的头部字段,比如 X-xxx

(3)请求的 Content-Type 值不是 application/x-www-form-urlencodedmultipart/form-datatext/plain,等等

给一个预检请求设置headers: { 'X-test': 'CORS' } // 增加一个自定义的头部字段,触发预检请求

预检请求报文:

请求首部字段 Access-Control-Request-Method 告知服务器,实际请求将使用 POST 方法。 请求首部字段 Access-Control-Request-Headers 告知服务器,实际请求将携带一个自定义请求首部字段:x-test。服务器据此决定,该实际请求是否被允许。

响应首部字段 Access-Control-Allow-Methods 表明服务器允许客户端使用哪些方法发起请求。 响应首部字段 Access-Control-Allow-Headers 表明服务器允许请求中携带字段 x-test。

实际请求的报文:

实际请求中发送了 X-test 头部字段,响应状态码 200 OK。

可以看到,预检请求中使用了更多的头部字段来完成访问控制。那么,CORS 相关的请求头部字段和响应头部字段共有哪些呢?

1.http请求头部字段

(1)Origin:表示预检请求或实际请求的源站。

(2)Access-Control-Request-Methods :头部字段用于预检请求。其作用是,将实际请求所使用的 HTTP 方法告诉服务器。

(3)Access-Control-Request-Headers: 头部字段用于预检请求。其作用是,将实际请求所携带的首部字段告诉服务器。

注意,以上请求头部字段无须手动设置,当使用 XMLHttpRequest 对象发起跨域请求时,它们已经被设置就绪

2.http响应头部字段

(1)Access-Control-Allow-Origin:表明服务端允许的域名

(2)Access-Control-Allow-Methods:该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求。

(3)Access-Control-Allow-Headers:如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段。

(3)Access-Control-Allow-Credentials:需要携带cookie信息时,服务端需要将withCredentials设置为true,否则会报错

(4)Access-Control-Max-Age:该字段可选,用来指定本次预检请求的有效期,单位为秒。表示在第一次预检请求发出后,指定时间内再访问该接口时会直接发送实际请求,而不需要先发预检请求。过了指定时间后,会再要求先发送预检请求

优势

使用CORS简单请求,对于前端来说无需做任何配置,与发送普通ajax请求无异。唯一需要注意的是,需要携带cookie信息时,需要将withCredentials设置为true即可。CORS的配置,完全在后端设置,配置起来也比较容易,目前对于大部分浏览器兼容性也比较好。CORS优势也比较明显,可以实现任何类型的请求。如果不需要兼容IE10以下的浏览器CORS会是一个好的选择

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值