CORS 的预检请求
CORS 跨域的前后端配置
简单请求和非简单请求
CORS 预检请求
简单请求
条件(同时满足)
请求方法:HEAD,GET,POST
请求头:Accept,Accept-Language,Content-Language,Last-Event-ID,Content-Type:只限于 application/x-www-form-urlencoded、multipart/form-data、text/plain
验证过程
客户端发送简单请求,会在请求头增加一个 Origin 头信息,指定该请求发送方的域,提交给服务器用于判断是否接受该跨域请求。
两种情况下服务器会接受该跨域:
Access-Control-Allow-Origin:*
如果服务器同意该跨域访问,正常返回数据,并在响应头中携带添加Access-Control-Allow-Origin
头信息。Access-Control-Allow-Origin
设置的允许跨域的地址中包含请求的Origin
。
非简单请求
不满足上面简单请求规则的请求都是非简单请求。比如请求方法是 PUT 或 DELETE,或者 Content-Type 字段的类型是 application/json。
避免多次请求,axios 的 post 封装为简单请求
1 | import QS from "qs"; |
后端通过 app.use(bodyParser())将 req.body 解析为对象
预检请求
当浏览器检测到需要发送一个非简单的跨域请求时,浏览器会拦截该请求,发送一个预检请求到服务器,旨在询问服务器是否同意这个非简单的跨域请求,服务器通过返回指定内容表示是否同意。
成功的预检请求响应
- Access-Control-Allow-Credentials:是否携带 cookie
- Access-Control-Allow-Methods
该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支 持的方法,而不单是浏览器请求的那个方法。这是为了避免多次”预检”请求。 - Access-Control-Allow-Headers
如果浏览器请求包括 Access-Control-Request-Headers 字段,则 Access-Control-Allow-Headers 字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在”预检”中请求的字段。 - Access-Control-Max-Age
该字段可选,用来指定本次预检请求的有效期,单位为秒。上面结果中,有效期是 20 天(1728000 秒),即允许缓存该条回应 1728000 秒(即 20 天),在此期间,不用发出另一条预检请求。
预检通过
一旦服务器通过了”预检”请求,以后每次浏览器正常的 CORS 请求,就都跟简单请求一样,会有一个 Origin 头信息字段。服务器的回应,也都会有一个 Access-Control-Allow-Origin 头信息字段。
完整的复杂请求例子
1 | // index.html |
server
1 | let express = require('express') |
cookie 参数
1 | path:指定 cookie 影响到的路径 |