大家都是草台班子,我干了这么多年开发,能把跨域问题说清楚的人也没几个 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
shadowyue
0.35D
V2EX    程序员

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

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

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

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

疑问 2:
既然开发环境前端都可以自行处理跨域,那我打包部署的时候部署一样应该可以啊?
类似这个帖子的疑问: 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  
caryqy
    1
caryqy  
   2024-07-11 11:16:30 +08:00   3
lemon1997
    2
lemon1997  
   2024-07-11 11:16:53 +08:00   1
挺好的,有些后端跨域也整不明白
netizenHan
    3
netizenHan  
   2024-07-11 11:18:57 +08:00   1
,干了好几年后端,一直听有这个问题,其实也不知道为啥
sofm
    4
sofm  
   2024-07-11 11:19:23 +08:00   1
楼主说的有道理,跨域很好解决。 但有些人又不去研究下
FreshOldMan
    5
FreshOldMan  
   2024-07-11 11:20:10 +08:00   1
InDom
    6
InDom  
   2024-07-11 11:20:14 +08:00   5
看了开头,习惯性先看末尾是否引流,v50 之类的。

作为一个后端,很早之前就理解跨域的缘由,虽然一开始不太理解明明很简单的东西,身边为什么有人就是不理解,就算知道也讲不明白是怎么回事。

后来也释然了,不理解我也不想讲了,反正你知道这样不行就行了,我可不打算把 URI 与 URL 的区别也将清楚。

我也不想扩展太多,因为懂得早就懂得,剩下的你讲了也听不进去,听进去也理解不了。
qq135449773
    7
qq135449773  
   2024-07-11 11:22:26 +08:00   3
能讲明白跨域该没工作还是没工作,世界就是这样的残酷~
yangxin0
    8
yangxin0  
   2024-07-11 11:24:14 +08:00
需要的时候问一下 GPT 就好了。
shadowyue
    9
shadowyue  
OP
   2024-07-11 11:24:53 +08:00   3
@qq135449773 没事,乐观点,懂得多总比懂的少更让人感觉充实。
ounxnpz
    10
ounxnpz  
   2024-07-11 11:26:13 +08:00   2
作为后端,我都直接:
```
Access-Control-Allow-Origin: *
```
SleepyRaven
    11
SleepyRaven  
   2024-07-11 11:26:32 +08:00
/t/1056317 这个帖子确实给我看流汗了
villivateur
    12
villivateur  
   2024-07-11 11:27:12 +08:00
所以,如果有一个恶意浏览器,故意给某些网站开跨域后门,那用户/被跨域的站点就会被坑。
shadowyue
    13
shadowyue  
OP
   2024-07-11 11:28:00 +08:00
@bluicezhen 开发环境可以,线上还是建议你是用白名单,安全点。
dumbass
    14
dumbass  
   2024-07-11 11:28:44 +08:00   2
「 我认为这是现在的前端脚手架提供的一个极其糟糕的功能。
它把跨域这个完全由后端处理的问题默默的在开发环境处理掉了,并且还附加了接口地址改写的各种功能
导致前后端都稀里糊涂的。跨域问题就应该在开发环境处理掉。 」
不认同,这就是脚手架要做的啊。
wangxiang
    15
wangxiang  
   2024-07-11 11:29:01 +08:00   5
- 有跨域问题请求不通,帮忙放开一下。
- 你就不能搜一下 JS 怎么解决跨域,别什么都来麻烦后台
shadowyue
    16
shadowyue  
OP
   2024-07-11 11:30:12 +08:00   1
@wangxiang 汗流浃背了哥,遇到这样的后端是最麻烦的。
TimPeake
    17
TimPeake  
   2024-07-11 11:30:27 +08:00   1
唉 认知差异太大。
做好自己就行,别为这些事情上头。
你要知道 工作 3 年的前端/后端,网络知识不通的人大把抓, nginx 基础配置都不懂的更是遍地都是。
告诉自己不要生气,你是来打工的。
dumbass
    18
dumbass  
   2024-07-11 11:30:50 +08:00   1
正好准备看面试,学到了新知识
到时候要是没面上拿你试问
shadowyue
    19
shadowyue  
OP
   2024-07-11 11:31:48 +08:00
@bojackhorseman 如果没有这个功能,前后端会早早的尝试在开发环境进行跨域处理。
正如我标题的第一句话,既然大家都是草台班子,问题还是早点暴露的好,不要留到线上环境去。
9c04C5dO01Sw5DNL
    20
9c04C5dO01Sw5DNL  
   2024-07-11 11:31:49 +08:00   4
额。。。我认为楼主要是完全搞明白了,就不会说是 “跨域” 了,也不知道这个词最开始是谁给翻译的。 这个词严谨的说法应该叫 “跨源” , 源包含了:域、协议或端口 。"同源策略"中的 “源” 说的也是这个
magicZ
    21
magicZ  
   2024-07-11 11:31:56 +08:00   1
这个问题概念都忘了,我直接把 nginx 配置记到笔记了,遇到就粘上去
ruke
    22
ruke  
   2024-07-11 11:33:56 +08:00   1
都用 jsonp 去吧
justdoit123
    23
justdoit123  
   2024-07-11 11:34:18 +08:00   2
太正常了。

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
    24
eWS2mq278TTzoj0O  
   2024-07-11 11:35:26 +08:00
@wangxiang 已经有画面了。。
shadowyue
    25
shadowyue  
OP
   2024-07-11 11:35:48 +08:00
@ruke 还留在上个时代的开发确实会说这个技术方案,虽然也不是不行,只要公司的安全组允许所有接口都是 get 就行
iphantom
    26
iphantom  
   2024-07-11 11:35:59 +08:00   1
点个赞~
darksword21
    27
darksword21  
PRO
   2024-07-11 11:37:08 +08:00
我是后端,我是理解跨域,只是之前每次听到前端说代理之类的让我很懵,我印象里前端就是静态文件怎么本地还要启动 http server 了,后来抓着前端同时聊才逐渐了解
ReinerShir
    28
ReinerShir  
   2024-07-11 11:37:23 +08:00   1
居然被人贴了。。

你说的这些知识我都知道

解释一下那个帖子,那个问题是部署平台的问题(具体哪个鬼平台我就不说了),部署完后不生效一直使用的老缓存,导致我以为是 vite 在搞鬼,现在已经 OK 了,直接请求的后端接口
shadowyue
    29
shadowyue  
OP
   2024-07-11 11:37:52 +08:00
@justdoit123 你这个内容解释起来恐怕吵架更多,害怕.jpg
wangritian
    30
wangritian  
   2024-07-11 11:39:02 +08:00
我起后端项目,跨域头是必备的中间件,origin 不能设置*,要根据请求头的 Host 来
shadowyue
    31
shadowyue  
OP
   2024-07-11 11:39:15 +08:00
@ReinerShir 没事哥,我草包一个,只是借用你的贴聊聊而已。
tyrone2333
    32
tyrone2333  
   2024-07-11 11:39:28 +08:00
@wangxiang 我们公司有个网关,各种过滤和阉割,跨域都好几个地方配置,连后端老大都不知道哪里配
TimPeake
    33
TimPeake  
   2024-07-11 11:39:39 +08:00
@ReinerShir 生产环境跟 vite 没有一毛钱关系 ,“部署完后不生效一直使用的老缓存,导致我以为是 vite 在搞鬼” 这个就是你自己认知的问题了。
jevirs
    34
jevirs  
   2024-07-11 11:39:53 +08:00   1
做了些前端面试,大家都能把同源策略说清楚,也能背出 jsonp 、proxy 等八股文方案,真问到 cors 相关的头是哪几个,全歇菜
herewego
    35
herewego  
   2024-07-11 11:40:12 +08:00   1
我是全栈,我啥都知道[狗头]
WonderCc
    36
WonderCc  
   2024-07-11 11:40:16 +08:00   1
以前实习面试的时候有问过,说到要咋做,我还背过 nginx 什么的,现在完全忘记
xiaowunai
    37
xiaowunai  
   2024-07-11 11:40:24 +08:00   1
世界本来就这样
能用就行
4Et5ShxMIq58n6Lr
    38
4Et5ShxMIq58n6Lr  
   2024-07-11 11:40:41 +08:00   1
这个其实看看 MDN 就知道了,上面基本上都说了,关于跨域的相关的只是,例如为啥发 option 请求
shadowyue
    39
shadowyue  
OP
   2024-07-11 11:41:37 +08:00
@jevirs 会背和真的会用还是有区别。
比如前端资源的缓存策略怎么做比较好,我面试也经常问,能用实践回答让我满意的就少多了。
shadowyue
    40
shadowyue  
OP
   2024-07-11 11:42:40 +08:00
@laobobo 太对了哥,mdn 上面很多答案都是现成的。
害怕的是我不知道面试过多少前端,都不知道有 mdn 这个东西,汗流浃背了
Xrall
    41
Xrall  
   2024-07-11 11:42:59 +08:00   1
后面的都能理解,第一点的确是不知道的。
之前就有时候会出现前端请求跨域,然后就会让后端处理一下跨域。
但是奇怪的就是游览器报跨域后端压根没有收到任何请求。
那么 OP 说的第一点就让我稍微想得通一点了,肯定是出现了 node 的服务出现了异常导致没法正确转发。
回想一下也是每次遇见这种情况往往是本地重启一下服务就好了。
想想以前全都是 ajax 一把嗦,后端配置好了还真没遇见过前面说到的这种问题。
lisongeee
    42
lisongeee  
   2024-07-11 11:43:49 +08:00   2
你这有点东西都没说清楚,不严谨,比如你说的《为啥我见过浏览器发 option 请求?》

这叫预检请求,不是每次都发,只有当发起复杂请求时才会发起,使用 fetch 、xhr 发起 无复杂参数(浏览器认为无副作用)的 get 和 post 是 *没有预检请求* 的,而且服务器能收到并且正确处理

但是也需要返回允许 cors 的 headers ,否则浏览器不会把 response 传递给 js
shadowyue
    43
shadowyue  
OP
   2024-07-11 11:44:46 +08:00
@Xrall 浏览器的做法是跨域了直接把请求拦截了,后端啥日志都不会有的。
byte10
    44
byte10  
   2024-07-11 11:44:49 +08:00   1
(⊙o⊙)…有一个东西 我觉得应该可以讲一下,为啥会有跨域问题。。。不限制 跨域会有什么问题,小程序为啥没有跨域问题。
nthin0
    45
nthin0  
   2024-07-11 11:47:37 +08:00 via iPhone   1
感谢讲解,学习了
ylh1024
    46
ylh1024  
   2024-07-11 11:49:26 +08:00
chrome --user-data-dir="C:/Chrome dev session" --disable-web-security --disable-site-isolation-trials
silencil
    47
silencil  
   2024-07-11 11:50:05 +08:00   1
很好!我个人觉得我是理解跨域的,也知道是浏览器的策略。但是一旦被问的话,估计也是说不上来。另外,我就是这种三四年的菜鸡,也不会配置 Nginx 。
Xrall
    48
Xrall  
   2024-07-11 11:50:27 +08:00
@shadowyue #43 这个是知道的游览器做了拦截。
只不过还是有一点点疑惑,那就是我描述的这种情况的话。
原因是游览器发送了真正的请求地址从而被游览器认定跨域拦截,
还是说像描述中一样是因为一些问题导致 node 启动的服务没有正确转发呢?
yuezhiyuan
    49
yuezhiyuan  
   2024-07-11 11:50:30 +08:00
但是在浏览器环境下,为了安全,浏览器只允许 js 访问固定的几个响应头。
----
如何理解这句话,例如接口返回了不允许的响应头,浏览器报跨域错误吗
GloryIsMine
    50
GloryIsMine  
   2024-07-11 11:52:24 +08:00   1
这种问题在配置对象存储服务的时候也会遇到吧 不算小众问题吧
yuezhiyuan
    51
yuezhiyuan  
   2024-07-11 11:52:40 +08:00   1
跨域比想象中要复杂许多,例如 Access-Control-Allow-Origin: * 等于*时另外个跨域 cookie 的参数就不能等于 true

另外受 cdn 、nginx 的影响,响应头会被不小心更改到,导致产生跨域
zliea
    52
zliea  
   2024-07-11 11:56:52 +08:00 via iPhone
不过一个项目开发的时候,如果项目组前后台沟通流畅的话,提前规划接口与前台页面的路径。
比如
{BASEURL}/yewuA/h5/是前台部署路径,{BASEURL}/yewuA/api/是后台部署路径。
前端可以控制 baseurl 放在不同环境的环境变量中打包。
前端脚手架来解决跨域问题是可以的,总不能现在还是让前端启动配置一个和测试生产环境一样的 nginx 来调试吧。
现在前端由于是编译的,没法做到使用类似../../这种相对路径请求接口,但前端接口请求一定不能是完整地址待域名端口(类似 http://域名:端口/)这种,一定要是直接到根这种。
azhangbing
    53
azhangbing  
   2024-07-11 11:57:05 +08:00   1
因为跨域限制是古早时候 浏览器的同源策略 那时候一般都放在同个域名,端口下的 很早很早了
yusf
    54
yusf  
   2024-07-11 11:58:50 +08:00   1
跨域是浏览器行为
xiaochena
    55
xiaochena  
   2024-07-11 11:59:45 +08:00   1
@bluicezhen Access-Control-Allow-Origin: * 就不能带 cookie 了哦
0IuL7w7X5K2HJxZf
    56
0IuL7w7X5K2HJxZf  
   2024-07-11 12:02:30 +08:00
跨域的问题不只是原理,你以为理解了,MDN 那个文档看过无数遍了,但是每次和前端对接都会出现新的问题,xhr ,fetch ,axios ,不同的库对 cors 的使用方法和处理方式不同,烦人的很,而且现在的跨域限制的更多了,以前能行的办法突然发现某些情况下又不行了。
iOCZS
    57
iOCZS  
   2024-07-11 12:04:43 +08:00   1
人们制定了很多规则,但是又不善于记忆规则。
encro
    58
encro  
   2024-07-11 12:04:52 +08:00   2
讲点核心的:


首先,你得理解为什么浏览器要限制跨域:
1 ,比如我公司的静态 js 和图片,被某大流量网站直接引用了,我流量不直接被刷爆?
2 ,某域名直接 iframe 之类嵌套,或者引用我的资料,打着李逵额名号,其实是李鬼。

所以,浏览器限制了跨域请求。

问:那么,我们开发时,想要访问线上接口怎么办?

答:我们可以用 vite 之类 nodejs 的代理功能,通过代理访问线上接口,代理一词的意思是我们访问本地的接口,代理服务器通过本地程序(非浏览器)转发到线上接口。

问:如果我们确实有线上项目的跨域请求的需求怎么办?

答:我们可以在服务器设置 Access-Control-Allow-Origin ,将我们自己人加入白名单。


跨域,就是这么简单!
sofm
    59
sofm  
   2024-07-11 12:05:55 +08:00
@Xrall 跨域时, 后端有收到请求,也响应了,前端有收到了响应,但是浏览器发现了跨域,存在安全问题,就报错拦截了。
bertonzh
    60
bertonzh  
   2024-07-11 12:07:06 +08:00   3
「我认为这是现在的前端脚手架提供的一个极其糟糕的功能」
你这个观点不对。

本地开发服务器会提供接口代理,它的一个重要的背景是:
世界上绝大多数网页服务,网页域名跟接口域名是一样的,也就是线上一般不会存在跨域问题。

开发工具做这个代理逻辑,仅仅是为了跟线上保持一致而已。

确实存在接口域名跟网页域名不一样的时候,但是这不应该是常态。因为即使处理了跨域的问题,还有三方 cookie 的问题等着你。
itakeman
    61
itakeman  
   2024-07-11 12:08:52 +08:00 via Android   1
前端的事情前端完成,别什么都麻烦后端
AV1
    62
AV1  
   2024-07-11 12:11:01 +08:00   1
@shadowyue
跨域请求,后端是有日志的。
而且如果是 GET 请求,在后端看来,甚至是一次成功的请求,它感知不到自己返回的结果被浏览器拦截了。

我们看到的“Access to fetch at 'xxxx' from origin 'xxxx' has been blocked by CORS policy”异常,是发生在接受返回值的阶段,而不是发请求的阶段:
JS>浏览器>服务器>浏览器 >JS
shadowyue
    63
shadowyue  
OP
   2024-07-11 12:12:34 +08:00
@bertonzh 原来如此,感谢你的回复。因为目前我这边的项目页面域名和服务端域名都是不相同的。
你这个说法也很有道理。
shadowyue
    64
shadowyue  
OP
   2024-07-11 12:13:22 +08:00
@DOLLOR 感谢你的补充,那是我搞错了。
JKKK
    65
JKKK  
   2024-07-11 12:16:17 +08:00   1
跨域本质上是个浏览器的安全策略,配合 HTTP 头信息安全的使用其他域名的资源
shadowyue
    66
shadowyue  
OP
   2024-07-11 12:17:13 +08:00
@yuezhiyuan #49

浏览器是能接受任何响应头的。只是限制了 js 能读取哪些头。
想让 js 访问其它的响应头,需要用 Access-Control-Allow-Headers 来加白名单。
nevermoreluo
    67
nevermoreluo  
   2024-07-11 12:18:03 +08:00   1
我觉得核心逻辑是清楚地,但是实际务会因为一些框架或者代理之类的导致其他的异常的边界情况。并不能说这个问题就是这样。
我遇到过的边界情况包括但是不限于,运维同学 nginx 配置和研发同学代码框架冲突导致 header 被重复添加,旧的浏览器个别版本不支持 wildcard 等等等等。
这东西说难不难,但是实际业务中还是要跟着 response 去跟逻辑去处理或者规范框架配置。
thoo61871
    68
thoo61871  
   2024-07-11 12:19:56 +08:00   1
后端转小会社全干,刚好上个月遇到这个问题学习了一下。那个帖子真的看得我一头冷汗。
Xu3Xan89YsA7oP64
    69
Xu3Xan89YsA7oP64  
   2024-07-11 12:26:05 +08:00   1
前端基本都知道跨域,但是能分清楚同源和同站的人真的很少,CSP 以及 cookie 的 sameSite 是同站
brucexueth
    70
brucexueth  
   2024-07-11 12:27:10 +08:00   1
“跨越了不同的域(名)想要去请求资源” 是有欠缺的,其实不只是域名,端口不同也算的。本质是因为同源策略,可以看看 https://zh.wikipedia.org/wiki/%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5
QlanQ
    71
QlanQ  
   2024-07-11 12:27:49 +08:00
这几天折腾 canvas 加载 s3 源站的图片,折腾到现在都没弄好,就是提示 提示跨域了,s3 的我配置的没问题哇,别的图片都可以正常展示,就是 放到 canvas 就不行。。。
NessajCN
    72
NessajCN  
   2024-07-11 12:34:35 +08:00
你自己也没咋搞清楚嘛...
其实大多数前端在 cors 上踩坑都是因为下面这段:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#including_credentials

简单说就是带 cookies 或者其他什么 with credential 的请求,浏览器都默认发 "same-origin" 的请求。

而且就算你特意在 fetch() 里面设了 {credentials: "include"} ,
服务端的返回头里必须把 Access-Control-Allow-Origin 指定好特定的 origin, "*" 是不允许的会弹错
另外只要 cookie 的 "SameSite" 属性是"Lax"或"Strict",也还是没法正常发 cookie 的

我敢打赌在座的各位前后端,必然都或多或少在这上面踩过坑。
谁要是确实第一遍看文档就注意到这里并且一次编码完成就再也没弹过错请大胆 at 我,受我一拜。
Jinnrry
    73
Jinnrry  
   2024-07-11 12:38:27 +08:00 via Android   1
以前负责面试招人(3 到 5 年的后端),我发现最少一半以上的人讲不明白跨域,还有很多人讲不明白 cookie session ,但是这些人谈起 jvm 调优,谈起 java 源码却能头头是道
iyaozhen
    74
iyaozhen  
   2024-07-11 12:41:44 +08:00
@bluicezhen 不行 你这样,如果想携带 cookie ,给* 不可以,必须确定的域名
iyaozhen
    75
iyaozhen  
   2024-07-11 12:48:19 +08:00   2
确实很多人不知道,可能还有另一部分原因,现在很多项目都是短平快,大家遇到问题总是希望有一个办法解决所有问题。不巧的是跨域这个问题很复杂,https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS 你没读 10 来遍是搞不清楚的。更悲剧的是,很多人都是看的二手资料,只知道了其中一部分,甚至是错的。
所以有了背 nginx 配置、jsonp 、Access-Control-Allow-Origin: * 等等片面的解决方案,毕竟具体问题具体分析很麻烦,反正这些都配置/用上,能跑就行
anjingdexiaocai
    76
anjingdexiaocai  
   2024-07-11 12:49:51 +08:00 via Android   1
说的很细
freezebreze
    77
freezebreze  
   2024-07-11 12:50:25 +08:00   1
这种问题 我只能说 what can i say
iyaozhen
    78
iyaozhen  
   2024-07-11 12:51:04 +08:00   2
还有楼主说的 [浏览器会阻止给和页面地址不同的域名发请求] 其实也不完全是,就像前面说的,具体分析,有些请求是要等服务端返回,浏览器看一下 response header 才知道能不能跨域,这时候其实服务端已经处理成功返回了,只是返回的时候被浏览器拦截了。简单验证方法就是 Charles 抓个包,能看到 Charles 这边都是正常的。
vincent7245
    79
vincent7245  
   2024-07-11 12:55:25 +08:00   2
我就不一样了,我从来没觉得自己是草台班子,我觉得我是公司里带领大家向前冲的大佬 (/狗头)
jsq2627
    80
jsq2627  
   2024-07-11 13:00:53 +08:00   1
> 我认为这是现在的前端脚手架提供的一个极其糟糕的功能。
> 它把跨域这个完全由后端处理的问题默默的在开发环境处理掉了,并且还附加了接口地址改写的各种功能

强烈认同,见过无数初学者和草台班子搞不明白这个问题,最后索性直接在生产环境运行 vite dev
kaedeair
    81
kaedeair  
   2024-07-11 13:09:10 +08:00
@encro #58 跨域属于浏览器安全问题,主要是为了防止 xss
my3157
    82
my3157  
   2024-07-11 13:12:23 +08:00
因为现在的框架都默认配置和处理了, 就像以前用 .net 框架的 webform 一样, 能写, 但不知道细节, 同样的问题还有 cookie , 另外现在浏览器的 localstorage/indexdb , 每次打开里面都是一坨乱七八糟的数据, 甚至敏感数据也直接往里面存
bytesfold
    83
bytesfold  
   2024-07-11 13:14:02 +08:00 via iPhone   1
收藏了等于我会了
Nosub
    84
Nosub  
   2024-07-11 13:16:01 +08:00
很多时候,是因为我自己不懂,然后就说其他人都不懂;

是的,我说的就是 OP ;

这两个都是在前端(客户端)解决:

前端解决 angular 跨域访问的问题
https://www.nosub.net/posts/p/98
前端解决 angular 跨域访问的问题-通过 Nginx
https://www.nosub.net/posts/p/99
hukei
    85
hukei  
   2024-07-11 13:17:42 +08:00
zackzergzeng
    86
zackzergzeng  
   2024-07-11 13:20:23 +08:00   1
所有问题都是因为用了浏览器这个全是窟窿眼的应用系统闹的
ooolooo
    87
ooolooo  
   2024-07-11 13:29:35 +08:00   1
@Nosub 代理服务器不是服务器了? 前端写服务端代码就是前端问题啦?
这样的后端更可笑, 原来是你自己的文章啊, 前端大佬!!!
skuuhui
    88
skuuhui  
   2024-07-11 13:36:48 +08:00   1
没有吧,术业有专攻,做过全栈开发的或者和前端对接频繁的知道很正常吧,一个纯后端开发强迫人家知道也没啥用,不知道也正常。但也不代表草布草台的吧,这玩意也不是多深奥东西说白了这个和 set-cookie ,302 都是一套浏览器规则罢了,说不定哪天来个 100%国产纯血浏览器还限制呢。
Liam1997
    89
Liam1997  
   2024-07-11 13:37:19 +08:00   1
@Nosub 你贴的第一个链接,就是开发模式下,前端脚手架启动一个 nodejs 服务器转发啊,和 OP 说的有区别么
LuckyLauncher
    90
LuckyLauncher  
   2024-07-11 13:37:51 +08:00
@Nosub 代理服务器和 Nginx 什么时候属于前端范畴了?浏览器什么时候能启动 Nginx 了
shadowyue
    91
shadowyue  
OP
   2024-07-11 13:38:47 +08:00   8
@Nosub #84 哥你真是让我汗流浃背
第一个帖子明显是和 vue 的脚手架一样是开发环境解决跨域的方案,你试试部署时候能用吗?
第二个帖子都上 nginx 了还算前端吗?
你真是给这个帖子提供了最佳素材
Promtheus
    92
Promtheus  
   2024-07-11 13:40:36 +08:00
这和前后端有啥关系 这不是常识吗。。一般后端都会写一些简单的前端代码的。
poorcai
    93
poorcai  
   2024-07-11 13:41:37 +08:00   1
哈哈哈哈,学习了
wqhui
    94
wqhui  
   2024-07-11 13:41:43 +08:00   1
东西太多了,没法全认真学这么细,知道怎么解决就好
wildnode
    95
wildnode  
   2024-07-11 13:42:16 +08:00   1
大约有 50% 的后端会掏出 postman 请求一下然后说我这没问题啊
大约有 30% 的后端会问你,CORS 是啥玩意,我加什么响应头?
大概只有 20% 是正常人
Nosub
    96
Nosub  
   2024-07-11 13:42:24 +08:00
@shadowyue NO ,我说的前端开发人员通过客户端解决,Client 理解为前端没毛病吧。
shadowyue
    97
shadowyue  
OP
   2024-07-11 13:42:51 +08:00
@NessajCN #72
我不明白你想说我哪里没搞清楚。
你发的链接是 fetch api ,我上面解释的都是 XMLHttpRequest ,虽然它两都是用来请求接口的,但是还是有区别的。
wildnode
    98
wildnode  
   2024-07-11 13:43:02 +08:00
@wildnode 忘了加防杠提示了(我遇到的,不代表其他大佬们身边的数据
Nitsuya
    99
Nitsuya  
   2024-07-11 13:43:57 +08:00   1
一样一样, 都是草台班子, 干了 11 年了,经常看同事写屎山,有时候说两句,有时候我都懒得说. 也不指望他们有啥长进, 毕竟总要有人干 CRUD 的代码.
Tyrant1984
    100
Tyrant1984  
   2024-07-11 13:44:00 +08:00   1
每个字我都认识,我真棒~
1  2  3  
关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3482 人在线   最高记录 6679       Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 35ms UTC 00:44 PVG 08:44 LAX 17:44 JFK 20:44
Do have faith in what you're doing.
ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86