大家都是草台班子😂,我干了这么多年开发,能把跨域问题说清楚的人也没几个😅

2024 年 7 月 11 日
 shadowyue
跨域只会出现在浏览器环境中!
跨域只会出现在浏览器环境中!
跨域只会出现在浏览器环境中!
重要的事情说三遍。
我知道为啥很多后端开发很疑惑为啥有这种问题,因为纯服务端之间应该没有这个概念。

首先解释清楚什么情况下,会被认定成跨域:
页面地址的域名是 A ,但是接口请求的地址是 B 。这就是跨域,跨越了不同的域(名)想要去请求资源。

在浏览器中会发生的现象:
浏览器会阻止给和页面地址不同的域名发请求。
这跟语言无关,这就是一个在浏览器环境下的安全策略。

怎么办:
请把你的页面域名加入白名单。使用响应头 Access-Control-Allow-Origin 来处理。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
或者使用 nginx ,前端请求的接口还是用网页的域名,但是用 ngxin 转发到服务端的地址去。

拓展:
其实后端的响应头是能帮助前端做不少事情的。
比如 Access-Control-Allow-Methods 这个头,能约定接口只能发 post,还是 get
比如 Access-Control-Allow-Headers,后端通常会返回很多响应头字段,
但是在浏览器环境下,为了安全,浏览器只允许 js 访问固定的几个响应头。
如果想让前端访问其它的响应头字段,就可以通过 Allow-Headers 进行配置。

比如如果你想让前端做一个下载进度条,正确的返回 Content-Length ,前端就能计算下载进度。

比如 Content-Disposition ,只要你声明本次请求是一个附件并正确的有文件名称,
就能自动触发浏览器的文件下载,不需要前端在额外做任何事情。

疑问 1:为啥开发环境都没事啊?
类似这个帖子的疑问: https://v2ex.ih06.com/t/1056317
开发的时候前端本地页面地址是 localhost ,接口地址肯定是其他的,为啥不跨域?
因为现在前端项目,开发用的脚手架通常会在本地用 node.js 启动一个 http 服务,
本来发给 B 域名的请求,会被代码改写成请求到 localhost(或者 127.0.0.1)的 http 服务去,
然后通过 node.js 的转发进行真正的接口调用。
正如我上面说的,跨域只会存在于浏览器环境,node.js 可以给任何域名发 http 请求。

我认为这是现在的前端脚手架提供的一个极其糟糕的功能。
它把跨域这个完全由后端处理的问题默默的在开发环境处理掉了,并且还附加了接口地址改写的各种功能
导致前后端都稀里糊涂的。跨域问题就应该在开发环境处理掉。

疑问 2:
既然开发环境前端都可以自行处理跨域,那我打包部署的时候部署一样应该可以啊?
类似这个帖子的疑问: https://v2ex.ih06.com/t/1056317
因为普通的前端构建打包后,只有前端的代码。不会包含任何 node.js 的代码。
现在的前端项目就是真真正正的一堆静态资源。不像以前的 jsp 需要服务器跑。
只需要一个 ngxin 来提供静态文件访问的能力就行。

疑问 3:不对啊,我在自己网站可以随便链接好多别的域名的涩图,不也跨域了?
对图片这种资源限制没那么严格,其它类型资源也有这个问题。
现在是可以通过 CSP 策略来告诉浏览器,我只能从什么域名加载什么样的资源。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy

疑问 4:为啥我见过浏览器发 option 请求?
正如上面说的,这是浏览器的安全策略。但是有一个问题,如果浏览器从来就没请求过 B 域名,
它怎么知道页面当前域名在不在 B 域名的白名单中呢?
所以就有 option 请求,一个不带任何数据的请求,就是问一下 B 域名的服务器,你给我了啥权限。


个人结尾来点感想:
我不是嘲讽说谁谁菜不懂这个技术点,我干了这么久开发,深知每个人都有自己的局限性。
比如我上面的解释就是我当前的理解,如果有错误那就是我的局限性。
看了我上面解释的一大堆,猜到我本职是后端开发还是前端开发了吗?
如果我上面有任何错误欢迎指正批评。
我知道 V2EX 这里经常嘲讽前端是娱乐圈,但是前端开发作为客户端开发的一个分支,
在加上由于 electron 这个牛逼项目的普及,大家使用的客户端软件,事实上很多都已经是用前端页面来做了。
比如 vscode 就是。包括各种小程序等等,本质都是 web 端的扩展。
只要有技术力还是能做出很棒的软件的。(我之前听说马斯克的很多项目 UI 层都是 electron ,上太空都行)
50861 次点击
所在节点    程序员
272 条回复
magicZ
2024 年 7 月 11 日
这个问题概念都忘了,我直接把 nginx 配置记到笔记了,遇到就粘上去
ruke
2024 年 7 月 11 日
都用 jsonp 去吧
justdoit123
2024 年 7 月 11 日
太正常了。

web 环境跟 server 环境经常混为一谈。狭义一点的 web 环境,应该是指浏览器环境。 但是 http server 不是只服务于浏览器。

经典的几个莫名其妙的问题以及神奇操作。

1. cookie 与 session 有什么区别?二者不是之间替代品,没什么好比较。
2. cookie 与 jwt token 有什么区别?二者不是之间替代品,没什么好比较。
3. 在浏览器环境,把 jwt token 塞 Authentication header 里。那请问你的 jwt token 不是需要让 js 访问吗?那不是等于会泄露在某处?
4. 把公开的 API 加上 CSRF 保护。这类 API ,一般会用服务于 sdk 、app 、server 2 server ,这种场景下防什么 CSRF 攻击。CSRF 攻击只在浏览器发生。server 可以分流,身份信息 放在 cookie 里的,是浏览器流量,需要 CSRF 保护,放在 Authentication header 里的,是一些非浏览器流量,不需要 CSRF 保护。
...
eWS2mq278TTzoj0O
2024 年 7 月 11 日
@wangxiang 已经有画面了。。
shadowyue
2024 年 7 月 11 日
@ruke 还留在上个时代的开发确实会说这个技术方案😅,虽然也不是不行,只要公司的安全组允许所有接口都是 get 就行
iphantom
2024 年 7 月 11 日
点个赞~
darksword21
2024 年 7 月 11 日
我是后端,我是理解跨域,只是之前每次听到前端说代理之类的让我很懵,我印象里前端就是静态文件怎么本地还要启动 http server 了,后来抓着前端同时聊才逐渐了解
ReinerShir
2024 年 7 月 11 日
居然被人贴了。。

你说的这些知识我都知道

解释一下那个帖子,那个问题是部署平台的问题(具体哪个鬼平台我就不说了),部署完后不生效一直使用的老缓存,导致我以为是 vite 在搞鬼,现在已经 OK 了,直接请求的后端接口
shadowyue
2024 年 7 月 11 日
@justdoit123 你这个内容解释起来恐怕吵架更多,害怕.jpg
WaldenHorizon
2024 年 7 月 11 日
我起后端项目,跨域头是必备的中间件,origin 不能设置*,要根据请求头的 Host 来
shadowyue
2024 年 7 月 11 日
@ReinerShir 没事哥,我草包一个,只是借用你的贴聊聊而已。
tyrone2333
2024 年 7 月 11 日
@wangxiang 我们公司有个网关,各种过滤和阉割,跨域都好几个地方配置,连后端老大都不知道哪里配😅
TimPeake
2024 年 7 月 11 日
@ReinerShir 生产环境跟 vite 没有一毛钱关系 ,“部署完后不生效一直使用的老缓存,导致我以为是 vite 在搞鬼” 这个就是你自己认知的问题了。
jevirs
2024 年 7 月 11 日
做了些前端面试,大家都能把同源策略说清楚,也能背出 jsonp 、proxy 等八股文方案,真问到 cors 相关的头是哪几个,全歇菜
herewego
2024 年 7 月 11 日
我是全栈,我啥都知道[狗头]
WonderCc
2024 年 7 月 11 日
以前实习面试的时候有问过,说到要咋做,我还背过 nginx 什么的,现在完全忘记😅
xiaowunai
2024 年 7 月 11 日
世界本来就这样
能用就行
4Et5ShxMIq58n6Lr
2024 年 7 月 11 日
这个其实看看 MDN 就知道了,上面基本上都说了,关于跨域的相关的只是,例如为啥发 option 请求
shadowyue
2024 年 7 月 11 日
@jevirs 会背和真的会用还是有区别。
比如前端资源的缓存策略怎么做比较好,我面试也经常问,能用实践回答让我满意的就少多了。
shadowyue
2024 年 7 月 11 日
@laobobo 太对了哥,mdn 上面很多答案都是现成的。
害怕的是我不知道面试过多少前端,都不知道有 mdn 这个东西,汗流浃背了😅

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://v2ex.ih06.com/t/1056504

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX