CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。当两个地址scheme+host+port不一样的时候,就是不一样域的地址。html
cors是浏览器的策略,目的是为了保证网络上资源调用的安全性。若是浏览器仅仅是访问资源,不会存在跨域问题,好比访问图片,JS等文件;可是若是是读取元数据,就会受到浏览器CORS的限制,好比AJAX请求。前端
浏览器将CORS请求分红两类:简单请求(simple request)和非简单请求(not-so-simple request)。web
- 请求方法是如下三种方法之一:HEAD,GET,POST
- HTTP的头信息不超出如下几种字段:Accept,Accept-Language,Content-Language,Last-Event-ID,Content-Type: 只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
知足以上条件的为简单请求,不然为非简单请求(好比常见的自定义header字段,或是Content-Type:application/json等)。json
对于简单请求,浏览器发送请求时会在request header里添加Origin字段,标记请求源。服务器处理请求后,返回响应信息,浏览器检查响应信息,发现响应头里没有设置Access-Control-Allow-Origin等跨域信息,会拦截请求,并抛出错误。跨域
非简单跨域请求在发送时,浏览器会增长一个options预检请求。大概流程以下:浏览器
当非简单请求里添加过自定义请求头字段,则 response 里须要同步设置 Access-Control-Allow-Headers: '自定义header字段名',此时预检请求才会校验经过。缓存
// Request
headers: {
'Content-Type': 'application/json',
'system': 'web',
'version': 'v1.0'
}
复制代码
// Response
'Access-Control-Allow-Headers': 'Content-Type, system, version'
复制代码
跨域读取cookie, 须要知足以下三个条件:安全
通常前端只能读取resopnse body,若是想要读取自定义的response header信息,就须要设置Access-Control-Expose-Headers字段,指定须要暴露出去的header字段,这样前端就能够经过JS来读取响应头里的header信息了。服务器
// js
let system = response.headers.get('system');
复制代码
// response
Access-Control-Expose-Headers: 'system'
复制代码
若是某个请求类型是delete,则响应头里须要设置Access-Control-Allow-Methods字段。markdown
// response
Access-Control-Allow-Methods: 'delete'
复制代码
可使用 Access-Control-Max-Age 设置预检请求的有效期。在这段时间内,同个请求的预检请求只会请求一次。
// response
Access-Control-Max-Age: 100 // 100秒内使用缓存过的预检请求
复制代码
值为 * 或是固定的域名,表示容许跨域请求的域名。
值为 true/false,表示服务器是否接收Cookie。想要跨域传递cookie,除了服务端Access-Control-Allow-Credentials: true接收cookie外;客户端请求也须要设置withCredentials: true,表示浏览器赞成发送cookie。另外 Access-Control-Allow-Origin 必须是个指定的域名。
值为请求头里设置的自定义header字段。
值为须要暴露出去的header字段。
跨来源的请求只接受三种类型GET、HEAD,POST。除此以外,若是是其它请求类型,则响应头里须要设置Access-Control-Allow-Methods: 'xxx'。
Access-Control-Max-Age 指定本次预检请求的有效期,单位是秒。