记一个预检(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了。