跨域——CORS、JSONP

出去溜达了一圈面试,发现很多公司爱问CORS技术,辣mo~这一节我们来研究下CORS吧 ~


跨域——CORS、JSONP_第1张图片
开场图.png

什么是跨域?

一个url地址的组成:协议,域名,端口号,如果这几个因素任意一个不相同的情况,都属于不同的域。不同的域之间的请求,就叫做“跨域”。

跨域的存在原因,是因为浏览器的“同源策略”。同源策略的存在可以保护用户隐私信息,防止身份伪造等。只有相同的域名,协议,端口号才能够正常通信。

值得注意的是,跨域并不是请求发不出去,而是服务端能接收到请求并且返回数据结果,这个数据结果被浏览器拦截了。

跨域的解决方式有哪些?

老生常谈,面试常问的问题,JSONP,CORS,postmessage,iframe,nginx代理巴拉巴拉顺扣就能说出来的答案,但是实际运用上呢?
这里先提JSONP,CORS两种,其他的后续补充 ~

1、JSONP
简单来说,jsonp是带有回调函数callback的json,但是它的局限性在于,JSONP只能实现GET请求。jsonp需要通过script标签引入(script标签是不受同源策略限制的)。



获取数据的地址后面跟着callback参数,这个参数名一般是跟后端协商格式得到的,返回后调用callback函数。

jsonp优缺点
优点:兼容性好,可以在更古老的浏览器中运行,请求完毕之后通过调用callback函数获取结果。
缺点:只能支持GET请求。

在CORS标准之前,jsonp请求只能仅限于GET请求,直到CORS标准出来,市场上大部分的浏览器都支持CORS。

2、CORS
支持CORS请求的浏览器一旦发现请求跨域,会对请求进行一些特殊处理,实现了CORS的服务器,接受请求,并且做出响应。

客户端不需要对跨域请求做任何特殊处理。实现CORS通信的关键是服务器,只要服务器实现了CORS接口,就可以跨源通信。

浏览器将跨域请求分为简单请求非简单请求

简单请求满足以下条件:
(1)、请求方式是:HEAD GET POST
(2)、HTTP头信息不超过以下字段:
Accept 、 Accept-Language、Content-Language、
Content-Type:application/x-www-form-urlencoded、 multipart/form-data、text/plain

简单请求

浏览器判定该请求为简单请求的时候,会在request头部添加origin(协议+域名+端口)字段,表示我们的请求源,CORS会将该字段作为跨域标识。

CORS接收到请求后,会判断Origin是否在允许的源范围内,如果是在范围内的,则服务端会在响应头部添加Access-Control-Allow-Origin、Access-Control-Allow-Credentials等字段。如果不在范围内,响应头没有包含Access-Control-Allow-Origin,浏览器会抛出“同源检测异常”。

  • Access-Control-Allow-Origin:该字段是必须。如果值是“ * ”,表示接受任意域名的请求,不过出于服务器安全考虑,一般都不会设置为*。Access-Control-Allow-Origin也可以返回允许访问的源,如果在允许范文源的范围内,则浏览器不会拦截请求响应。

  • Access-Control-Allow-Credentials:该字段可选。表示是否允许发送cookie,这个值只能设置为true,否则不要添加该字段。并且,当Access-Control-Allow-Origin设置为*,该字段就算设置为true,出于安全考虑,是不会发送cookie。

  • Access-Control-Expose-Headers:该字段可选。该字段是一个逗号分隔开的字符串,指定浏览器CORS请求会额外发送的头部字段。

这里需要注意的是,即时服务器同意发送cookie,如果浏览器没设置,也不会发送cookie的,开发者需要设置withCredentials为true,将请求带上cookie

非简单请求

对服务器有特殊要求的请求,在正式通信之前,会增加一次HTTP查询请求,称之“预检查请求”。浏览器先询问服务器,当前网页域名是否在可允许访问的范围内,以及可以使用哪些头部信息字段,状态码为204,只有当预检通过了,浏览器才会发出正式请求,这时候才会返回200。

“预检”请求用的方法就是OPTIONS,表示这个请求是用来询问。头部的Origin用来标识请求源。一旦服务器通过“预检”请求,以后每次浏览器正常的CORS请求,都会有一个Origin头字段,服务器回应也会有一个Access-Control-Allow-Origin头部字段。

写在最后

CORS比JSONP更强大,JSONP只支持GET请求,但是兼容性强大,CORS可以支持所有http请求。

跨域——CORS、JSONP_第2张图片
image.png

你可能感兴趣的:(跨域——CORS、JSONP)