跨域 CORS 入门 前端调接口被浏览器拦下是怎么回事
前端页面调后端接口,代码看着没错,接口拿工具单独测也通,一放进浏览器就报一串红字,里面有个刺眼的 CORS。很多人第一反应是接口坏了,其实坏的不是接口,是被浏览器的同源策略拦了。本文讲清什么叫同源、为什么工具里测不出来、正确的解法在服务器一侧,以及放行范围别乱写这条安全红线。
先认识同源策略。浏览器有个铁规矩:一个页面只能自由读取和自己同源的接口,所谓同源,是协议、域名、端口三样全都一样。页面在 a.com,接口在 b.com,是跨域;域名一样但一个 8080 端口一个 80 端口,也是跨域;http 和 https 混着来,同样不行。这条规矩是防恶意网站的:没有它,你登录着银行的标签页,随便打开一个坏网站,它就能借你的登录状态偷偷调银行接口。规矩本身是保护你的。
最迷惑新手的是现象:明明用接口测试工具调是通的。原因在于跨域时请求其实发出去了,服务器也正常处理并返回了数据,是浏览器在最后一步把结果扣下,不交给页面代码,还在控制台报那句 has been blocked by CORS policy。测试工具没有同源策略这一层,所以一路畅通。记住这个判断法:工具里通、浏览器里报 CORS,就是跨域问题,别再去翻接口代码了。
正解在服务器一侧,不在前端。接口的响应里要带上一个声明:Access-Control-Allow-Origin,告诉浏览器我允许哪个来源的页面来读我。比如只允许自己的前端站,就把值写成那个前端的域名。还有一种情况叫预检:当请求带了自定义请求头或者用了 PUT、DELETE 这类方法时,浏览器会先偷偷发一个 OPTIONS 请求来探路,服务器必须能正确回应它,正式请求才会被放行,很多跨域故障实际卡在这一步。另外,请求要带 Cookie 时,还得加 Allow-Credentials 声明,并且来源不能用通配符,两者是配套的。
落地上,Nginx 里给接口加几行 add_header 就能办,后端框架大多有现成的 CORS 中间件或配置项,填上允许的来源名单即可。开发阶段图省事用代理转发绕过去可以,但那只是临时招,上线环境还是要把响应头配正。不建议为了少配几个域名就把来源写成星号通配,那等于向全网敞开。
最后这条红线单独强调:Allow-Origin 的范围就是你家大门的钥匙发放名单。只放行自己信任的那几个前端域名,挨个写明;星号通配再配上允许带凭证的设置,浏览器会直接判它无效,而且真能这么配通的话,任何网站都能借用户的登录状态调你的接口,风险极大。排查跨域问题时顺序也固定:先看响应里有没有放行头,再看预检请求有没有被正确回应,最后看放行名单里有没有漏掉你实际用的那个来源和端口,十有八九就出在这三处。
- 点赞
- 收藏
- 关注作者
评论(0)