一、问题描述
前端在请求跨域接口时,可能会遇到一种错误,类似于:
Access to fetch at 'http://xxx.com/index' from origin 'http://yyy.com' has been blocked by CORS policy: Request header field pragma is not allowed by Access-Control-Allow-Headers in preflight response.
在Network面板上,你还会发现会似乎有两条一样的请求:
其中,可以明显看到多了一个preflight
类型的请求。
二、问题排查
预检请求(preflight)在跨域请求中是比较常见的:
1.CORS 预检请求(CORS Preflight request)介绍
CORS 预检请求是用于检查服务器是否支持 CORS 即跨域资源共享。
它一般是用了以下几个 HTTP 请求首部的 OPTIONS 请求:Access-Control-Request-Method 和 Access-Control-Request-Headers,以及一个 Origin 首部。
当有必要的时候,浏览器会自动发出一个预检请求;所以在正常情况下,前端开发者不需要自己去发这样的请求。
举个例子,一个客户端可能会在实际发送一个 DELETE 请求之前,先向服务器发起一个预检请求,用于询问是否可以向服务器发起一个 DELETE 请求:
OPTIONS /resource/foo
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: origin, x-requested-with
Origin: https://foo.bar.org
如果服务器允许,那么服务器就会响应这个预检请求。并且其响应首部 Access-Control-Allow-Methods 会将 DELETE 包含在其中:
HTTP/1.1 200 OK
Content-Length: 0
Connection: keep-alive
Access-Control-Allow-Origin: https://foo.bar.org
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Max-Age: 86400
这里可能会有个疑惑:CORS跨域预检请求在什么情况下才会触发?这个后续文章再进行探究。
2.问题原因
在Nextwork中模拟一下跨域请求:
Request header field pragma is not allowed by Access-Control-Allow-Headers in preflight response.
这就是因为在跨域预检请求的响应中并不允许携带pragma
请求头。
只要把pragma
请求头移除即可: