跨域资源共享CORS与jsonp
目录
- 跨域资源共享CORS
- 概念
- 什么情况下会触发CORS
- CORS请求行为与分类
- jsonp简要介绍
- XMLHttpRequest简要介绍
跨域资源共享CORS
1.概念
说实话这个概念是今天第一次见到,可能这个概念属于前后端数据接口如何交互,并没有机会去接触了解这个场景,按理说也属于前端工程的一部分。
它的全称是cross-origin resource sharing,完全是按字面翻译过来的,好理解。
CORS是 HTML5 提供的标准跨域解决方案,我们所谈到的内容都是基于浏览器的,因为受限于浏览器的同源策略,所以才有这样的标准出现,离开浏览器,就不存在这些概念了吧。
2.什么情况下会触发CORS?
业务场景很普遍存在于多个域名下数据的交互,公司的业务不可能只有一个域名,例如公共的文件服务器就需要接受来自不同的也无方,此时就需要用到cors。
CORS的触发相对于ajax是无感知的,因为是浏览器帮你去做了一系列的事情(添加一些首部字段信息,来表明这是采用了跨域资源共享)。
CORS的实现需要服务器支持,只要服务器比如nginx设置了,浏览器就会在特定的情况下触发。
所以触发的条件即:该请求跨域了,且服务器支持跨域资源共享。
3.CORS请求行为与分类
跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。
简而言之就是cors会对服务器产生副作用的方法进行预检,即发送一个类型为options的请求,去探知服务器是否支持该请求域名的cors。
分为简单请求与复杂请求,因为在不同的分类下触发的条件不一致。
上面有提到“对服务器产生副作用的方法”才发起预检请求,简单请求就是包含了不会产生服务作用的方法。
3.1 简单请求(ajax)为同时满足以下条件:
- 方法
- GET
- HEAD
- POST
- Content-Type 的值仅限于下列三者之一:
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
简单请求时的首部字段有2个最基本的特点:
请求报文中,会有origin字段表明请求来源:
origin: http://www.example.com
响应报文中,存在:
Access-Control-Allow-Origin: *
这样就完成了一个简单请求的跨域资源请求。
3.2 非简单请求
当请求满足下述任一条件时,即为非简单请求,非简单请求会先发送预检请求:
- 方法
- put
- delete
- options
- trace
- Content-Type 的值不属于下列之一
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
- 人为设置了如下首部字段以外的
- Accept
- Accept-Language
- Content-Language
- Content-Type (but note the additional requirements below)
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
只要满足以上任一条件都认为是非简单请求,最常见的是http请求时,将Content-Type
设置为application/json
。
一个非简单请求的过程如下
3.3 跨域请求携带凭证 一般而言,对于跨域 XMLHttpRequest请求,浏览器不会发送身份凭证信息。如果要发送凭证信息,需要设置
xhr.withCredentials = true
在请求的时候设置该字段会带上cookie,如果服务器支持携带凭证,即服务器设置了
Access-Control-Allow-Credentials: true
简单请求携带凭证如图所示:
**对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin 的值为“*”。**因为cookie遵循同源策略,即协议,域名与端口相关。
以上参考:
HTTP访问控制(CORS)
跨域资源共享 CORS 详解