一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情。
什么是 cors
cors (Cross-Origin Resource Sharing, 跨域资源共享)由一系列 HTTP 响应头组成,这些 HTTP 响应头决定浏览器是否阻止前端 js 代码跨域获取资源
浏览器的同源安全策略默认会阻止网页 “跨域” 获取资源,但如果接口服务器配置了 cors 相关的 HTTP 响应头,就可以解除浏览器端的跨域访问限制
cors 注意事项
-
cors 主要在服务器端进行配置,客户端浏览器无需做任何额外的配置,即可请求开启了 cors 的接口
-
cors 在浏览器中有兼容性,只支持 XMLHttpRequest Level2 的浏览器,才能正常访问开启了 cors 的服务器接口(如 IE10、Chrome4+、Firefox3.5)
cors 响应头(Access-Control-Allow-*)
Access-Control-Allow-Origin
-
响应头部中可以携带一个
Access-Control-Allow-Origin字段Access-Control-Allow-Origin: <origin> | * -
origin 参数的值指定了允许访问该资源的外域 URL
示例(只允许来自 studyNode.cn 的请求)
res.setHeader('Access-Control-Allow-Origin', 'http://studyNode.cn') -
如果指定了
Access-Control-Allow-Origin字段的值为通配符*,表示允许来自任何域的请求res.setHeader('Access-Control-Allow-Origin', '*')
Access-Control-Allow-Headers
-
默认情况下,cors 仅支持客户端向服务器发送如下九个请求头
- Accept
- Accept-Language
- Content-Language
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
- Content-Type(值仅限于 text/plain、multipart/form-data、application/x-www-form-urlencoded 三者之一)
-
如果客户端向服务器发送了额外的请求头信息,则需要在服务器端通过
Access-Control-Allow-Headers对额外的请求头进行声明,否则这次请求失败// 允许客户端额外向服务器发送 Content-Type 请求头和 X-Custom-Header 请求头 // 注意:多个请求头之间使用英文的逗号进行分割 res.setHeader('Access-Control-Allow-Headers','Content-Type,X-Custom-Header')
Access-Control-Allow-Methods
- 默认情况下,cors 仅支持客户端发起 GET、POST、HEAD 请求
- 如果客户端希望通过 PUT、DELETE 等方式发起请求服务器的资源,则需要在服务器端,通过
Access-Control-Allow-Methods来指明实际请求所允许使用的 HTTP 方法
// 只允许 POST、GET、DELETE、HEAD 请求方法
res.setHeader('Access-Control-Allow-Methods','POST、GET、DELETE、HEAD')
// 允许所有的 HTTP 请求方法
res.setHeader('Access-Control-Allow-Methods','*')
cors 请求的分类
客户端在请求 cors 接口时,根据请求方式和请求头的不同,可以将 cors 的请求分为俩大类
- 简单请求
- 预检请求
简单请求
同事满足俩个条件就属于简单请求
-
请求方式:GET、POST、HEAD 三者之一
-
HTTP 头部信息不超过以下几种字段,无自定义头部字段
- Accept
- Accept-Language
- Content-Language
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
- Content-Type(值仅限于 text/plain、multipart/form-data、application/x-www-form-urlencoded 三者之一)
预检请求
只要符合以下任何一个条件的请求,都需要进行预检请求
- 请求方式为 GET、POST、HEAD 之外的请求 Method 类型
- 请求头中包含自定义头部字段
- 向服务器发送了 application/json 格式的数据
在浏览器与服务器正式通信之前,浏览器会先发送 OPTION 请求进行预检,已获知服务器是否允许该实际请求,所以这一次的 OPTION 请求称为预检请求。服务器成功响应预检请求后,才会送到真正的请求,并且携带真是数据
简单请求和预检请求的区别
- 简单请求的特点:客户端与服务器之间只会发送一次请求
- 预检请求的特点:客户端与服务器之间会发生俩次请求,OPTION 预检请求成功之后,才会发起真正的请求