V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
shadowyue
V2EX  ›  程序员

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

  shadowyue · 2024-07-11 11:11:52 +08:00 · 43820 次点击
这是一个创建于 421 天前的主题,其中的信息可能已经有所发展或是发生改变。
跨域只会出现在浏览器环境中!
跨域只会出现在浏览器环境中!
跨域只会出现在浏览器环境中!
重要的事情说三遍。
我知道为啥很多后端开发很疑惑为啥有这种问题,因为纯服务端之间应该没有这个概念。

首先解释清楚什么情况下,会被认定成跨域:
页面地址的域名是 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://www.v2ex.com/t/1056317
开发的时候前端本地页面地址是 localhost ,接口地址肯定是其他的,为啥不跨域?
因为现在前端项目,开发用的脚手架通常会在本地用 node.js 启动一个 http 服务,
本来发给 B 域名的请求,会被代码改写成请求到 localhost(或者 127.0.0.1)的 http 服务去,
然后通过 node.js 的转发进行真正的接口调用。
正如我上面说的,跨域只会存在于浏览器环境,node.js 可以给任何域名发 http 请求。

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

疑问 2:
既然开发环境前端都可以自行处理跨域,那我打包部署的时候部署一样应该可以啊?
类似这个帖子的疑问: https://www.v2ex.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 ,上太空都行)
第 1 条附言  ·  2024-07-11 14:38:00 +08:00
感谢#62 @DOLLOR 和 #144 @bugfan 的补充。
如果未能正确设置跨域,那么接口会被浏览器正常请求,后端会正常收到。
但是返回的时候会被浏览器强行拦截。

感谢#105 @Liam1997 的补充。
浏览器地址栏的请求是不会有跨域问题的🤣 非常经典的问题。
272 条回复    2024-07-18 21:45:36 +08:00
1  2  3  
Nosub
    101
Nosub  
   2024-07-11 13:44:20 +08:00
@ooolooo 不要把无知当有趣,代理服务器既可以部署在客户端,也可以部署在服务器端;
shadowyue
    102
shadowyue  
OP
   2024-07-11 13:44:46 +08:00
@Nosub 我不明白你说的通过客户端解决是什么意思,不管是改配置还是改代码,常规都是在服务端处理跨域的。
Nosub
    103
Nosub  
   2024-07-11 13:46:07 +08:00
@shadowyue 我当然知道可以在服务器解决,我例子不是很明显了吗,你能修改钉钉的服务器吗?
shadowyue
    104
shadowyue  
OP
   2024-07-11 13:46:35 +08:00
@Nosub 对于普通前端开发来说,客户端就是浏览器。你可能是想说 nginx 页面直接装在用户的电脑上?
Liam1997
    105
Liam1997  
   2024-07-11 13:46:52 +08:00   ❤️ 1
@wildnode #95 还有很多是 GET 请求,直接把接口地址放入浏览器地址栏回车打开,截张图告诉你没问题的 😄
poorcai
    106
poorcai  
   2024-07-11 13:48:02 +08:00
确实想问下,既然跨域是浏览器决定的,那后端设置允许跨域是干啥的?(´・_・`)?
shadowyue
    107
shadowyue  
OP
   2024-07-11 13:48:07 +08:00
@Nosub #103 我觉得你还是有误解。
钉钉这种成熟的方案,肯定是你调用钉钉之前,需要去钉钉把你自己的域名添加到钉钉的白名单。
类似的微信等等平台都是这样的。
NessajCN
    108
NessajCN  
   2024-07-11 13:49:15 +08:00
@shadowyue 你看,从你纠结是 fetch api 还是 XMLHttpRequest 就说明你不光没搞懂 cors request 坑在哪里也没看明白我在说啥

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials
看这一段
「 In addition, this flag is also used to indicate when cookies are to be ignored in the response. The default is false. XMLHttpRequest responses from a different domain cannot set cookie values for their own domain unless withCredentials is set to true before making the request. The third-party cookies obtained by setting withCredentials to true will still honor same-origin policy and hence can not be accessed by the requesting script through document.cookie or from response headers.」

跟我上一个 fetch API 里的说明是不是一模一样?这跟你用哪个函数请求毫无关系
shadowyue
    109
shadowyue  
OP
   2024-07-11 13:49:42 +08:00   ❤️ 1
@Liam1997 #105
汗流浃背了哥😅 这个也是典中典。
补充一下,浏览器地址栏输入的任何链接,不会有跨域限制
ooolooo
    110
ooolooo  
   2024-07-11 13:50:04 +08:00
@Nosub #101 大佬何不开帖给大伙开开眼, 给俺菜鸟长长见识, 给大伙科普一下到底什么是客户端和服务器
abersheeran
    111
abersheeran  
   2024-07-11 13:50:25 +08:00   ❤️ 1
为了解决 CORS 的问题……我做的框架里,allow_cors 默认就是全开(能带上 cookies 用的那种),不懂这种东西的人太多了,框架提供太多安全性保护,反而这帮小白觉得难用(比如 Django CSRF )
mizuhokaga
    112
mizuhokaga  
   2024-07-11 13:51:18 +08:00   ❤️ 1
学习了,作为后端有时候写前端对跨域一直模模糊糊的
看完算是打通了,非常感谢 op 分享
LiuJiang
    113
LiuJiang  
   2024-07-11 13:51:23 +08:00   ❤️ 1
真的是这样,我对接过很多后端,TM 都不知道跨域。。。
NerbraskaGuy
    114
NerbraskaGuy  
   2024-07-11 13:52:29 +08:00   ❤️ 1
不懂跨域的后端挺多的,经常有后端把 get 请求粘浏览器地址栏里问我明明可以正常请求啊为啥是跨域问题....
shadowyue
    115
shadowyue  
OP
   2024-07-11 13:52:34 +08:00
@NessajCN #108 我这个帖子是讲怎么处理跨域的,重点是接口通不通。
你的侧重点是其它方面的话建议单开一贴讨论,感谢你的回复。
Nosub
    116
Nosub  
   2024-07-11 13:53:11 +08:00
@shadowyue 我的文章是针对前端开发人员调试用的,并不是针对普通客户,钉钉加入白名单是一种方式,但是:并不是所有环境都是可配置的,我文章也说了,如果你后端服务已经上线,而且已经设置了跨域,你前端要调试呢,当然你又说可以加入白名单,难道又要后端重新打包吗?
shadowyue
    117
shadowyue  
OP
   2024-07-11 13:57:37 +08:00   ❤️ 1
@Nosub #116
这就是跨域安全策略的意义所在。如果后端的配置你没有权利更改或者不能配合你修改,
最大的可能是,后端服务不属于你或者不是给你提供服务的。
其它有什么特殊情况导致后端无法协助配合处理跨域你可以讲讲。
asuraa
    118
asuraa  
   2024-07-11 14:00:06 +08:00
这有啥说不清的 跨域就是浏览器的一个限制本质上是为了安全防止跨站脚本攻击的
Gotchaaa
    119
Gotchaaa  
   2024-07-11 14:00:19 +08:00   ❤️ 1
上面讨论了很多,讲个冷知识,小程序不会跨域(应该吧
gowinder
    120
gowinder  
   2024-07-11 14:01:20 +08:00   ❤️ 1
分享得很好. 下次多来点.
NessajCN
    121
NessajCN  
   2024-07-11 14:01:42 +08:00
@shadowyue 行了行了看不懂直说就好了。新手没踩过 credential request 的 same-origin 坑看不懂很正常。
但你没真正排查过跨域大坑却来教别人啥是跨域就有点幽默了。
还是要多写写代码
sayitagain
    122
sayitagain  
   2024-07-11 14:04:28 +08:00
@bluicezhen #10 我也这样,但是上次遇到前端发起的预检请求 option 过不了这一段,还得额外加 Access-Control-Allow-Methods: GET, POST, PUT,DELETE,OPTIONS,PATCH 才能过,不知道为什么
kxg3030
    123
kxg3030  
   2024-07-11 14:05:40 +08:00
同理 能把编码问题解释清楚的人也没几个 能把二进制与文本区分开的人就更少了
encro
    124
encro  
   2024-07-11 14:06:23 +08:00
@kaedeair

xss 主要是配置项是 CSP ,我为了通俗简单一点,没提。
mercury233
    125
mercury233  
   2024-07-11 14:06:38 +08:00
代理解决不了跨域,用量一大就会被对方当爬虫封掉
kxg3030
    126
kxg3030  
   2024-07-11 14:06:38 +08:00
@bluicezhen 这样大部分情况也已处理 但是遇到前端要提交 cookie 这样设置是不行的哦 好了 你的知识又增加了
9c04C5dO01Sw5DNL
    127
9c04C5dO01Sw5DNL  
   2024-07-11 14:08:49 +08:00   ❤️ 3
@Nosub

我建议按照你的理解分为:前端,中端,后端。
或者:前端,前中端,中端,中后端,后端
或者:前端,前前中端,前中端,中端,中后端,中后后端,后端
或者:dddd
lolizeppelin
    128
lolizeppelin  
   2024-07-11 14:10:39 +08:00   ❤️ 1
写后端的不明白才是水平不到位....
但凡读过框架跨域处理的部分然后脑子想一想,随便再翻点资料就搞明白了
Nosub
    129
Nosub  
   2024-07-11 14:10:53 +08:00
@ooolooo 哈哈哈,字面意思的确有点歧义,其实我想说的是 [前端开发人员] 简写成了 [前端] ,这里是指客户端,我回复特别注明了,我觉得你没认真看就开喷,是不是有点过了。
mooyo
    130
mooyo  
   2024-07-11 14:12:17 +08:00   ❤️ 1
哈哈哈我跟你说我还见过后端认为服务器证书是申请了自动和域名绑定的,不需要自己设置的。
9c04C5dO01Sw5DNL
    131
9c04C5dO01Sw5DNL  
   2024-07-11 14:13:15 +08:00
@ooolooo 复议
xiaowunai
    132
xiaowunai  
   2024-07-11 14:13:27 +08:00
@byte10
webview 是可以控制的,打开开关的
其实浏览器 chrome 这种你也可以加个启动命令,禁止跨域拦截的
hellodigua
    133
hellodigua  
   2024-07-11 14:13:42 +08:00   ❤️ 1
@Nosub 小白看了你那个博文更迷糊,还是别误导人了
ooolooo
    134
ooolooo  
   2024-07-11 14:14:39 +08:00   ❤️ 1
@Nosub 众人皆醉你独醒, 是你开喷帖子的, 连服务端都拎不清都开喷 完事装无辜?
1183460943
    135
1183460943  
   2024-07-11 14:17:03 +08:00   ❤️ 1
我也特别看中跨域这块,基本每次面试必问,感觉一个成熟的开发者不可能不懂这个,但实际上还是很多人整不明白
caqiko
    136
caqiko  
   2024-07-11 14:17:54 +08:00   ❤️ 1
@poorcai #106 如果后端不允许跨域,那么由于浏览器的安全策略限制,https://example.com/index.html 页面里面的 js 不能通过 http 请求拿到接口 https://api.example.com/v1/get_users 的数据。但是这种应用场景又是客观存在的。
shadowyue
    137
shadowyue  
OP
   2024-07-11 14:19:54 +08:00
@NessajCN 我帖子的主要想解决的问题和你侧重点不同。我是草台,你是大神,你说的都对。
NessajCN
    138
NessajCN  
   2024-07-11 14:21:20 +08:00
@shadowyue 你至少先看懂了再来评价对还是错
7gugu
    139
7gugu  
   2024-07-11 14:21:29 +08:00   ❤️ 1
每次 CSP Error 我都要去提醒后台加跨域配置😅
bugfan
    140
bugfan  
   2024-07-11 14:22:53 +08:00   ❤️ 1
在浏览器中会发生的现象:
浏览器会阻止给和页面地址不同的域名发请求。
这跟语言无关,这就是一个在浏览器环境下的安全策略。

op 提到的这一段不太准确。

应该是浏览器会阻止 js 发起到的不同域之后的响应,绝大多熟请求是已经发出去了,是浏览器把响应拦截了(有一些参数可以让 js 请求发出去之前就拦截,但是大部分情况都是前者)。js 发请求包括 axios ,ajax (底层都是用 XMLHTTPRequest ),还有 fetch 这种的等等。。。

另外,html 标签发起的跨域请求是可以直接出去的。
codersdp1
    141
codersdp1  
   2024-07-11 14:29:07 +08:00
@ruke #22 好多年没听到这个词了
SSang
    142
SSang  
   2024-07-11 14:29:39 +08:00
让用户 `alias google-chrome='google-chrome --disable-web-security'` 从根本上解决跨域问题 😁😁

(我乱说的,别这么玩)
Xinu
    143
Xinu  
   2024-07-11 14:34:41 +08:00
@NessajCN 建议你看一下这个
https://www.ruanyifeng.com/blog/2016/04/cors.html

跨域本质还是浏览器安全策略的问题,op 说的一点问题没有
nexo
    144
nexo  
   2024-07-11 14:38:06 +08:00   ❤️ 1
非 xhr 的 get 不会跨域
fresco
    145
fresco  
   2024-07-11 14:40:35 +08:00   ❤️ 1
确实,非常多的人理解不了跨域,我服了
haoswil
    146
haoswil  
   2024-07-11 14:41:47 +08:00   ❤️ 1
在补一个,我们这边写前端的,vue 配置 publicPath 相对路径和绝对路径都不知道,我是 devops + SRE, 每次前端上线一个个这个 404 ,那个 404 , 简直智障
shadowyue
    147
shadowyue  
OP
   2024-07-11 14:42:53 +08:00
#119 @Gotchaaa 小程序我记得,你需要在腾讯的后台去配置一个域名白名单。
只有在白名单里边的地址你才能在小程序中请求。
guguji5
    148
guguji5  
   2024-07-11 14:44:16 +08:00
一篇文章给你看明白
https://zhuanlan.zhihu.com/p/271850279
shadowyue
    149
shadowyue  
OP
   2024-07-11 14:46:05 +08:00
@haoswil #146 好话题,你发个贴又能吵一架🤣
NessajCN
    150
NessajCN  
   2024-07-11 14:46:51 +08:00
@Xinu 还是那句话
你要是还在背八股备面试啃教材的话看不懂我发的这些正常
等你以后真需要踩跨域坑的话会回来查我发的这些链接的
cenbiq
    151
cenbiq  
   2024-07-11 14:47:28 +08:00   ❤️ 1
跨域问题的根本是由服务器输出 html 也就是开放的动态客户端代码导致的,所以浏览器必须配合服务器做同源策略来限制跨域以阻止跨站攻击等问题,在先天前后端分离的静态客户端 app 上就不存在这个问题,而这部分开发者到了浏览器的开发环境中就会发现存在“奇怪”的跨域问题。
salmon5
    152
salmon5  
   2024-07-11 14:48:10 +08:00   ❤️ 1
很多前端仔“缓存”更说不清楚。
Mandelo
    153
Mandelo  
   2024-07-11 14:49:12 +08:00
@Nitsuya #99 搞不好你同事也是这么想的
xiaoxiyiha
    154
xiaoxiyiha  
   2024-07-11 14:54:57 +08:00   ❤️ 1
追根溯源,是为了解决浏览器的“同源策略”
ukpkmk
    155
ukpkmk  
   2024-07-11 14:59:55 +08:00   ❤️ 1
学习了
brader
    156
brader  
   2024-07-11 15:03:34 +08:00   ❤️ 1
楼主,有一点我和你的理解恰恰相反,我认为能真正理解和吃透跨域原理的人,正是后端莫属,因为要实现一个完整的跨域功能,其交互行为几乎都是后端完成的,前端只需做基本配合即可。
我说的是真正自己去实现过跨域组建的后端,那种只调过跨域包或者调调 NGINX 的不算。

我描述几点跨域实现细节中,容易忽略或者易犯常识性错误的点(仅部分,不代表全部实现细节):

1 、对预检请求 OPTIONS 的处理,应在你的接口代码之前就进行拦截处理并响应(可以简单理解为做在前置中间件)。

2 、不是所有 OPTIONS 请求方法都是“预检请求”,浏览器还应同时通过 Access-Control-Request-Method 请求头明确告知实际请求中使用的方法,未提供则服务端不认为是预检请求,不应做对应处理。

3 、Access-Control-Allow-Origin: *,他不是万能的,仅在不需携带 Credentials 的情况下可以这么设置;如需携带 Credentials ,必须指定一个单一的域名。


从以上可以看出,想自行实现一个标准的跨域组件,需在浏览器的跨域标准基础上,结合自身项目的实际情况,来合理的设置各响应头,而不是一股脑的使用 Access-Control-Allow-Origin: * 。
如果一名后端不清楚浏览器的跨域标准,请问如何实现这样的跨域组件呢?所以我说后端最了解跨域就这个原因了。
Gotchaaa
    157
Gotchaaa  
   2024-07-11 15:04:13 +08:00
@shadowyue 对的,但是跟不跨域不矛盾
monologue520
    158
monologue520  
   2024-07-11 15:09:26 +08:00
@jevirs 我一般说 ACA 家族(手动滑稽)~
zackzergzeng
    159
zackzergzeng  
   2024-07-11 15:18:09 +08:00
@xiaowunai 你不可能让每个用户都手动禁止吧,这才是跨域真正的难点🤪
xiaowunai
    160
xiaowunai  
   2024-07-11 15:20:04 +08:00
@zackzergzeng
我不管,我就要,你自己想办法(狗头)
monologue520
    161
monologue520  
   2024-07-11 15:26:42 +08:00
@Jinnrry 这么离谱啊,果真是草台班子...
Canight
    162
Canight  
   2024-07-11 15:30:21 +08:00   ❤️ 1
我超,纯血技术帖
tywtyw2002
    163
tywtyw2002  
   2024-07-11 15:33:03 +08:00 via iPhone   ❤️ 1
看这帖子 想到了,之前那个帖子。

jwt 究竟是什么 哈哈哈
shadowyue
    164
shadowyue  
OP
   2024-07-11 15:37:34 +08:00
@Canight #162 怎么我的标题很像引流狗吗🐶
shenjinpeng
    165
shenjinpeng  
   2024-07-11 15:51:51 +08:00   ❤️ 1
待过几个公司, 身边人都知道啊, 前后端,测试 , 这种常见问题正常写接口的人都了解吧 哪有这么多草台班子
otakustay
    166
otakustay  
   2024-07-11 15:53:22 +08:00   ❤️ 1
楼主这堆还没涉及到 cache ,cors+preflight+cache 混一起才是一场精彩大戏
sofm
    167
sofm  
   2024-07-11 15:55:42 +08:00   ❤️ 1
跨域很好解决的。 思路也很清晰,咋就这么多人不学习,不思考呢
abelmakihara
    168
abelmakihara  
   2024-07-11 15:56:18 +08:00   ❤️ 1
纯前端不太可能不懂这个
不管是面试还是 devserver 多少会知道是干嘛的
大部分都是后端被迫兼职的
一看那个帖子果然又是..
yoyolichen
    169
yoyolichen  
   2024-07-11 16:06:59 +08:00
一个贴子被挂了两次 有点好笑 doge
baolongqishi
    170
baolongqishi  
   2024-07-11 16:23:33 +08:00
礼貌提问,我一般写 RPC 的,不写 web ,这个不懂应该正常吧( 2.5 年)
WJYuan
    171
WJYuan  
   2024-07-11 16:34:24 +08:00
lambdaq
    172
lambdaq  
   2024-07-11 16:38:25 +08:00
谁能讲明白 authority 和 origin 和 domain 的区别?
JoeDH
    173
JoeDH  
   2024-07-11 16:39:20 +08:00
@Jinnrry #73 培训包装简历的
me1onsoda
    174
me1onsoda  
   2024-07-11 16:54:08 +08:00
问题来了,为什么浏览器非要加上跨域限制,大家想方设法突破这个限制,理由也合情合理。这个限制的意义是什么
akakidz
    175
akakidz  
   2024-07-11 17:01:11 +08:00
@me1onsoda 因为安全第一,不考虑安全问题很轻松的就可以绕过跨域问题
9c04C5dO01Sw5DNL
    176
9c04C5dO01Sw5DNL  
   2024-07-11 17:03:26 +08:00
@brader 不同意哈,只能说需要后端对跨源 "协议" 比较清楚,也就是 "what"和 "how",但是涉及到 "why" 的地方,我认为前端需要比后端更清楚。
QlanQ
    177
QlanQ  
   2024-07-11 17:14:05 +08:00
@WJYuan 不光有跨域限制,还有缓存限制,缓存的图片,也会 cors 错误
xzh654321
    178
xzh654321  
   2024-07-11 17:17:24 +08:00
@otakustay 老哥可以讲解一下啊
gz65555
    179
gz65555  
   2024-07-11 17:27:41 +08:00
『我认为这是现在的前端脚手架提供的一个极其糟糕的功能』这点不同意。

很多时候前端开发环境是本地,请求接口是跨域,但是生产部署后就是同域名访问接口了。
billbob
    180
billbob  
   2024-07-11 17:33:30 +08:00
看到在要在服务端处理跨域这种人,不是坏,就是菜.
前端开发你可以,自己代理,比如 vue,angular,js 都可以处理跨域,比如:
我本地开发调用正式环境 API 测试,这时候你难道跑去让后端给你把线上服务器改吗?
还有就是调第三方的 API 都需要做代理.
brader
    181
brader  
   2024-07-11 17:36:54 +08:00
@me1onsoda #174 跨域限制这是有必要的,比如我们前端在 a.com ,API 接口在 b.com ,跨域资源共享是考虑到很多项目是这样的架构,提供了这样一种跨域策略。但即使配置了跨域,它任然为我们提供保护。
比如你的页面出于某种原因,被注入了 xx.com 的资源,那跨域保护还是起作用的,大大提升了攻击难度。
shadowyue
    182
shadowyue  
OP
   2024-07-11 17:39:40 +08:00
@billbob #180
你自己也说了开发环境。你要知道开发环境下前端对跨域处理的功能是无法应用到线上的。
生产环境你永远需要在服务端处理这个问题。
另外调用三方 API 也并不非要做代理。你使用云服务上传文件的接口,难道还需要让服务端转发一次文件上传流量?
你这个回复也很经典,非常感谢。
daliusu
    183
daliusu  
   2024-07-11 17:40:01 +08:00
@lemon1997 不是有些,我上班到现在,除了一些全栈和早期能力特别强的,后面在中厂碰到的后端能了解跨域并且解决的,基本都是会运维技术的,纯后端个个懵逼,能知道跨域是个后端问题的就算不错了,有些好几年经验的后端碰到跨域就让去找前端解决...
cirzear
    184
cirzear  
   2024-07-11 17:43:11 +08:00   ❤️ 1
学到了,感谢分享
osdnfpn
    185
osdnfpn  
   2024-07-11 17:49:24 +08:00   ❤️ 1
🐮🍺 大佬讲的很细致,感谢分享!
fank99
    186
fank99  
   2024-07-11 17:59:11 +08:00
@bluicezhen Access-Control-Allow-Origin: *的问题是,浏览器因为安全策略,不能设置为*的时候,不能带 cookie
tangping
    187
tangping  
   2024-07-11 18:07:30 +08:00
@giiiiiithub 和修仙一样的级别 哈哈
MMDeJeVS3GtMVLeu
    188
MMDeJeVS3GtMVLeu  
   2024-07-11 18:09:46 +08:00   ❤️ 1
我作为一个前端要说下:
1 、很多项目最终部署的时候是在一个域名下,自然就不存在跨域问题;
2 、很多后台不愿意(不会?)帮前端改 CORS ,前端为了调试,nodejs http 中间层很有必要,而且这个中间层不仅仅能做转发,劫持、mock 数据可以,所以它并不是一个糟糕的功能;
3 、我见过有企业做安全策略,Access-Control-Allow-Origin 不允许设置为*,只允许 GET 、POST
4 、存在即合理
zed1018
    189
zed1018  
   2024-07-11 18:21:48 +08:00   ❤️ 1
顺带补充一下,有没有 OPTION 请求取决于是不是简单请求。没记错的话大概是用 form 表单,或者 xmlrequest 发起的 urlencode/form 的 GET/POST 请求,并且头信息里没有一些奇奇怪怪的头的算是简单请求,这种请求会直接发起不会通过 OPTION 做 preflight 。

非简单请求则会用 OPTION 做 preflight ,preflight 做了以后各种 CORS 头都正确符合请求的需要才会发起正式请求,并且正是请求中也要包含符合需要的 CORS 头。
loy6491
    190
loy6491  
   2024-07-11 18:23:03 +08:00   ❤️ 1
我还以为有何高论,这些不是草台班子也应该懂的东西吗
fengyedzf
    191
fengyedzf  
   2024-07-11 18:34:42 +08:00   ❤️ 1
300 多个不懂的,嘿嘿
Torpedo
    192
Torpedo  
   2024-07-11 18:38:44 +08:00   ❤️ 1
我一直拿这个来测试后端水平。
倒不是说看后端了不了解跨域,而是和对应后端沟通跨域问题,并做了简单解释,但是他还不能理解的,肯定是菜逼。
onice
    193
onice  
   2024-07-11 18:40:06 +08:00   ❤️ 1
我是开发转安全,,学 web 安全第一课就是浏览器的安全措施之一,同源策略。正因为浏览器的同源策略,才会出现跨域的问题。
zsh2517
    194
zsh2517  
   2024-07-11 18:41:56 +08:00
@raviscioniemeche #123 前段时间做一个东西因为 emoji 表现问题改了好几次实现。然后最近闲下来,深入了解了一下 unicode 、emoji 与 UTF-X ,发现这玩意是个大坑。

而且更坑的一点是,很多平台特性实现不完全,以至于本来我想在笔记里举个例子,结果举出来的展现不出来😂
xzylzz
    195
xzylzz  
   2024-07-11 18:58:21 +08:00
@Nosub #84 你只能解决了开发环境的问题,线上环境跨域你前端怎么解决?
zsh2517
    196
zsh2517  
   2024-07-11 19:15:01 +08:00   ❤️ 2
@me1onsoda #174 @brader #181

防止资源注入主要是 CSP (内容安全策略)吧。写插件或者 user script 的应该遇到过。简单说是网站可以声明自己页面内允许的外部资源域名,不在域名内的会上报或者拒绝加载。
至于跨域的安全体现在哪,这个还真没仔细考虑过。刚才找 GPT 问了一下,沿用 #181 的例子,前端 a.com ,后端 b.com ,恶意网站 xx.com 。拦截的是从外部前端发到自己后端的情况

异常情况:假如没有 CORS 策略,且 b.com 的 cookie 设置了 samesite: None 。那么在 xx.com 就可以构造一个 fetch('https://b.com/someapi', {credentials: 'include'}),进而请求到 b.com 的数据。
而如果有 CORS 策略,在 options 预检请求时,b.com 的后端检测到非同源可以返回拒绝;或者返回固定的同源策略,比如 Access-Control-Allow-Origin: https://a.com ,浏览器也会拒绝 xx.com 的请求。

如果 a.com 请求 b.com 的话,因为 b.com 的 CORS 头说明了允许 a.com 、使用 XXX, YYY 方式请求,允许的 headers 是哪些……,如果 a.com 按照规则来,浏览器就不会拦截。

---

另一种情况,假如 a.com 被恶意注入了发往 xx.com 的资源。这个时候 a.com 请求 xx.com 是靠 xx.com 的 CORS 判定的,拦不住。用到的应该是 CSP 。例如 Content-Security-Policy: connect-src 'self' https://b.com;
watzds
    197
watzds  
   2024-07-11 20:22:33 +08:00
有些连 json 也整不明白
Bakyura
    198
Bakyura  
   2024-07-11 21:01:24 +08:00   ❤️ 1
看懂了,谢谢 op
leokun
    199
leokun  
   2024-07-11 21:03:11 +08:00   ❤️ 1
这个问题为什么会有这么多的讨论...
9dP06m83vIV00l72
    200
9dP06m83vIV00l72  
   2024-07-11 21:07:23 +08:00   ❤️ 1
你这属于不按套路出牌,没法提前预习准备答案呀。
1  2  3  
关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3468 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 32ms · UTC 00:10 · PVG 08:10 · LAX 17:10 · JFK 20:10
Developed with CodeLauncher
♥ Do have faith in what you're doing.