记一个预检(preflight)不通过导致的跨域失败

首先要知道什么时候需要预检?

答:“简单请求”不需要预检,其余的都需要预检。那什么是简单请求,什么不是呢?篇幅有限,请直接看mdn:

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS#preflighted_requests

由于之前对预检一无所知,就遇到了一个问题,就是前端向后端发起请求的时候,get和post得到截然不同的结果。在同样都设置了res.setHeader("Access-Control-Allow-Origin","*")允许跨域的情况下,get就能得到响应,post就报禁止跨域的错:

 

凭什么,post就要吃闭门羹?从XMLHttpRequest换到axios,都遇到一样报错。原因就是,大部分get请求都是简单请求,无需预检。所以get能获取响应。

查看network,“PreflightMissingAllowOriginHeader”,其实一开始看不懂这个报错,啥玩意儿啊。当然,这还是因为对预检不了解导致的:

 

百度一番,大致了解了Preflight的机制,这个报错意思是在Prefilght请求中没有Access-Control-Allow-Origin的响应头。换句话说,不仅后端app.post这个路由需要设置响应头,还要app.options对Preflight也设置允许跨域的响应头。这里不卖关子了,直接贴代码:

app.options('/p',function(req,res){
    res.setHeader("Access-Control-Allow-Origin","*")
    res.setHeader("Access-Control-Allow-Headers", "*");
    res.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
    res.setHeader("Access-Control-Expose-Headers", "*");
    res.end();   //这里响应一下,以免预检卡住,可能会阻塞正式请求也一直卡在pending的状态。
})

好了,post预检和正式请求都status ok了。

 

posted @ 2021-10-16 18:36  巨魔战将  阅读(3227)  评论(0编辑  收藏  举报