一文让你彻底搞懂跨域

跨域这个事情大家肯定都遇到过,也肯定都清楚是浏览器的同源策略导致的。
我一般遇到了就在网上抄一抄配置就解决了,但是关于跨域到底是怎么个原理一直没有深究,直到遇到了一个有趣的bug:

nginx配置了反向代理后,后端服务依旧403。

围绕着这个bug,来思考2个问题:

  1. 跨域是前端浏览器的限制,为什么需要后端来进行配置呢?
  2. 跨域只会发生在浏览器中,使用curl等工具发送请求是不会被跨域限制的,真的是这样吗?服务端是怎么判断请求来源是否是浏览器的?

注:
解决跨域有多种方法,本文只关注CORS.
浏览器对于简单请求和非简单请求处理的流程不一样,非简单请求会预先使用预检请求(OPTIONS)进行校验,简单请求会直接发送。这部分不是本文关注重点,不影响理解,下文都按照简单请求举例。

为什么需要后端配置?

想要搞清楚这个问题就要了解浏览器对于跨域请求的处理流程。

跨域请求流程图.png

根据以上流程,实际上无论是否同源,后端服务器都会接到请求,所以才会对非简单请求做预校验的优化。
真正判断是否可以跨域的不是浏览器,是后端服务器。后端服务器会在响应头中增加是否允许跨域的响应。Access-Control-Allow-Origin
浏览器根据响应头中的值来判断是否拦截。
所以是否允许跨域要在后端服务器进行配置。

只有浏览器请求会触发跨域校验吗?

跨域是浏览器的安全策略,那当然应该只有浏览器才会触发了?一开始我也是这么觉得的,但我的后端服务在被nginx反向代理后已经是同源了,却还是返回了403的响应,这是怎么回事呢?
我们就要搞清楚后端服务器是如何判断请求来源是否是浏览器的。
实际上是根据我们的请求头判断的,比如Origin,Referer等。具体的判断逻辑是后端服务器自己做,不同的web组件之间不尽相同。
此时我把后端服务器的debug打开,发现后端在校验Origin时报了不同源的异常,然后直接403返回给nginx,然后再返回到浏览器中。
通过curl验证一下:

curl -w '%{http_code}'  -X POST "http://ip:port/auth/login
# 返回值:
{"code":304,"msg":"用户名或密码错误","data":null}200

当我的请求头中不包含Origin时,可以正常响应。

curl -w '%{http_code}' -H "Origin: http://*.*.*.*"   -X POST "http://ip:port/auth/login"
# 返回值:
304

当增加Orgin时被拦截了。

至此,问题已经捋清楚了,解决方案有很多,我这里直接选择修改nginx,将请求头中的Orgin置空。

proxy_set_header    origin "";

问题解决。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容