![]() | 1 caryqy 2024-07-11 11:16:30 +08:00 ![]() |
2 lemon1997 2024-07-11 11:16:53 +08:00 ![]() 挺好的,有些后端跨域也整不明白 |
3 netizenHan 2024-07-11 11:18:57 +08:00 ![]() ,干了好几年后端,一直听有这个问题,其实也不知道为啥 |
4 sofm 2024-07-11 11:19:23 +08:00 ![]() 楼主说的有道理,跨域很好解决。 但有些人又不去研究下 |
![]() | 5 FreshOldMan 2024-07-11 11:20:10 +08:00 ![]() |
![]() | 6 InDom 2024-07-11 11:20:14 +08:00 ![]() 看了开头,习惯性先看末尾是否引流,v50 之类的。 作为一个后端,很早之前就理解跨域的缘由,虽然一开始不太理解明明很简单的东西,身边为什么有人就是不理解,就算知道也讲不明白是怎么回事。 后来也释然了,不理解我也不想讲了,反正你知道这样不行就行了,我可不打算把 URI 与 URL 的区别也将清楚。 我也不想扩展太多,因为懂得早就懂得,剩下的你讲了也听不进去,听进去也理解不了。 |
7 qq135449773 2024-07-11 11:22:26 +08:00 ![]() 能讲明白跨域该没工作还是没工作,世界就是这样的残酷~ |
![]() | 8 yangxin0 2024-07-11 11:24:14 +08:00 需要的时候问一下 GPT 就好了。 |
![]() | 9 shadowyue OP ![]() @qq135449773 没事,乐观点,懂得多总比懂的少更让人感觉充实。 |
![]() | 10 ounxnpz 2024-07-11 11:26:13 +08:00 ![]() 作为后端,我都直接: ``` Access-Control-Allow-Origin: * ``` |
![]() | 11 SleepyRaven 2024-07-11 11:26:32 +08:00 /t/1056317 这个帖子确实给我看流汗了 |
![]() | 12 villivateur 2024-07-11 11:27:12 +08:00 所以,如果有一个恶意浏览器,故意给某些网站开跨域后门,那用户/被跨域的站点就会被坑。 |
![]() | 13 shadowyue OP @bluicezhen 开发环境可以,线上还是建议你是用白名单,安全点。 |
![]() | 14 dumbass 2024-07-11 11:28:44 +08:00 ![]() 「 我认为这是现在的前端脚手架提供的一个极其糟糕的功能。 它把跨域这个完全由后端处理的问题默默的在开发环境处理掉了,并且还附加了接口地址改写的各种功能 导致前后端都稀里糊涂的。跨域问题就应该在开发环境处理掉。 」 不认同,这就是脚手架要做的啊。 |
15 wangxiang 2024-07-11 11:29:01 +08:00 ![]() - 有跨域问题请求不通,帮忙放开一下。 - 你就不能搜一下 JS 怎么解决跨域,别什么都来麻烦后台 |
![]() | 17 TimPeake 2024-07-11 11:30:27 +08:00 ![]() 唉 认知差异太大。 做好自己就行,别为这些事情上头。 你要知道 工作 3 年的前端/后端,网络知识不通的人大把抓, nginx 基础配置都不懂的更是遍地都是。 告诉自己不要生气,你是来打工的。 |
![]() | 18 dumbass 2024-07-11 11:30:50 +08:00 ![]() |
![]() | 19 shadowyue OP @bojackhorseman 如果没有这个功能,前后端会早早的尝试在开发环境进行跨域处理。 正如我标题的第一句话,既然大家都是草台班子,问题还是早点暴露的好,不要留到线上环境去。 |
20 9c04C5dO01Sw5DNL 2024-07-11 11:31:49 +08:00 ![]() 额。。。我认为楼主要是完全搞明白了,就不会说是 “跨域” 了,也不知道这个词最开始是谁给翻译的。 这个词严谨的说法应该叫 “跨源” , 源包含了:域、协议或端口 。"同源策略"中的 “源” 说的也是这个 |
![]() | 21 magicZ 2024-07-11 11:31:56 +08:00 ![]() 这个问题概念都忘了,我直接把 nginx 配置记到笔记了,遇到就粘上去 |
22 ruke 2024-07-11 11:33:56 +08:00 ![]() 都用 jsonp 去吧 |
23 justdoit123 2024-07-11 11:34:18 +08:00 ![]() 太正常了。 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 保护。 ... |
![]() | 24 eWS2mq278TTzoj0O 2024-07-11 11:35:26 +08:00 @wangxiang 已经有画面了。。 |
![]() | 25 shadowyue OP @ruke 还留在上个时代的开发确实会说这个技术方案,虽然也不是不行,只要公司的安全组允许所有接口都是 get 就行 |
![]() | 26 iphantom 2024-07-11 11:35:59 +08:00 ![]() 点个赞~ |
![]() | 27 darksword21 PRO 我是后端,我是理解跨域,只是之前每次听到前端说代理之类的让我很懵,我印象里前端就是静态文件怎么本地还要启动 http server 了,后来抓着前端同时聊才逐渐了解 |
![]() | 28 ReinerShir 2024-07-11 11:37:23 +08:00 ![]() 居然被人贴了。。 你说的这些知识我都知道 解释一下那个帖子,那个问题是部署平台的问题(具体哪个鬼平台我就不说了),部署完后不生效一直使用的老缓存,导致我以为是 vite 在搞鬼,现在已经 OK 了,直接请求的后端接口 |
![]() | 29 shadowyue OP @justdoit123 你这个内容解释起来恐怕吵架更多,害怕.jpg |
![]() | 30 wangritian 2024-07-11 11:39:02 +08:00 我起后端项目,跨域头是必备的中间件,origin 不能设置*,要根据请求头的 Host 来 |
![]() | 31 shadowyue OP @ReinerShir 没事哥,我草包一个,只是借用你的贴聊聊而已。 |
![]() | 32 tyrone2333 2024-07-11 11:39:28 +08:00 @wangxiang 我们公司有个网关,各种过滤和阉割,跨域都好几个地方配置,连后端老大都不知道哪里配 |
![]() | 33 TimPeake 2024-07-11 11:39:39 +08:00 @ReinerShir 生产环境跟 vite 没有一毛钱关系 ,“部署完后不生效一直使用的老缓存,导致我以为是 vite 在搞鬼” 这个就是你自己认知的问题了。 |
![]() | 34 jevirs 2024-07-11 11:39:53 +08:00 ![]() 做了些前端面试,大家都能把同源策略说清楚,也能背出 jsonp 、proxy 等八股文方案,真问到 cors 相关的头是哪几个,全歇菜 |
35 herewego 2024-07-11 11:40:12 +08:00 ![]() 我是全栈,我啥都知道[狗头] |
36 WonderCc 2024-07-11 11:40:16 +08:00 ![]() 以前实习面试的时候有问过,说到要咋做,我还背过 nginx 什么的,现在完全忘记 |
37 xiaowunai 2024-07-11 11:40:24 +08:00 ![]() 世界本来就这样 能用就行 |
![]() | 38 4Et5ShxMIq58n6Lr 2024-07-11 11:40:41 +08:00 ![]() 这个其实看看 MDN 就知道了,上面基本上都说了,关于跨域的相关的只是,例如为啥发 option 请求 |
![]() | 39 shadowyue OP @jevirs 会背和真的会用还是有区别。 比如前端资源的缓存策略怎么做比较好,我面试也经常问,能用实践回答让我满意的就少多了。 |
![]() | 40 shadowyue OP @laobobo 太对了哥,mdn 上面很多答案都是现成的。 害怕的是我不知道面试过多少前端,都不知道有 mdn 这个东西,汗流浃背了 |
![]() | 41 Xrall 2024-07-11 11:42:59 +08:00 ![]() 后面的都能理解,第一点的确是不知道的。 之前就有时候会出现前端请求跨域,然后就会让后端处理一下跨域。 但是奇怪的就是游览器报跨域后端压根没有收到任何请求。 那么 OP 说的第一点就让我稍微想得通一点了,肯定是出现了 node 的服务出现了异常导致没法正确转发。 回想一下也是每次遇见这种情况往往是本地重启一下服务就好了。 想想以前全都是 ajax 一把嗦,后端配置好了还真没遇见过前面说到的这种问题。 |
![]() | 42 lisongeee 2024-07-11 11:43:49 +08:00 ![]() 你这有点东西都没说清楚,不严谨,比如你说的《为啥我见过浏览器发 option 请求?》 这叫预检请求,不是每次都发,只有当发起复杂请求时才会发起,使用 fetch 、xhr 发起 无复杂参数(浏览器认为无副作用)的 get 和 post 是 *没有预检请求* 的,而且服务器能收到并且正确处理 但是也需要返回允许 cors 的 headers ,否则浏览器不会把 response 传递给 js |
![]() | 44 byte10 2024-07-11 11:44:49 +08:00 ![]() (⊙o⊙)…有一个东西 我觉得应该可以讲一下,为啥会有跨域问题。。。不限制 跨域会有什么问题,小程序为啥没有跨域问题。 |
![]() | 45 nthin0 2024-07-11 11:47:37 +08:00 via iPhone ![]() 感谢讲解,学习了 |
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 |
47 silencil 2024-07-11 11:50:05 +08:00 ![]() 很好!我个人觉得我是理解跨域的,也知道是浏览器的策略。但是一旦被问的话,估计也是说不上来。另外,我就是这种三四年的菜鸡,也不会配置 Nginx 。 |
![]() | 48 Xrall 2024-07-11 11:50:27 +08:00 @shadowyue #43 这个是知道的游览器做了拦截。 只不过还是有一点点疑惑,那就是我描述的这种情况的话。 原因是游览器发送了真正的请求地址从而被游览器认定跨域拦截, 还是说像描述中一样是因为一些问题导致 node 启动的服务没有正确转发呢? |
49 yuezhiyuan 2024-07-11 11:50:30 +08:00 但是在浏览器环境下,为了安全,浏览器只允许 js 访问固定的几个响应头。 ---- 如何理解这句话,例如接口返回了不允许的响应头,浏览器报跨域错误吗 |
50 GloryIsMine 2024-07-11 11:52:24 +08:00 ![]() 这种问题在配置对象存储服务的时候也会遇到吧 不算小众问题吧 |
51 yuezhiyuan 2024-07-11 11:52:40 +08:00 ![]() 跨域比想象中要复杂许多,例如 Access-Control-Allow-Origin: * 等于*时另外个跨域 cookie 的参数就不能等于 true 另外受 cdn 、nginx 的影响,响应头会被不小心更改到,导致产生跨域 |
![]() | 52 zliea 2024-07-11 11:56:52 +08:00 via iPhone 不过一个项目开发的时候,如果项目组前后台沟通流畅的话,提前规划接口与前台页面的路径。 比如 {BASEURL}/yewuA/h5/是前台部署路径,{BASEURL}/yewuA/api/是后台部署路径。 前端可以控制 baseurl 放在不同环境的环境变量中打包。 前端脚手架来解决跨域问题是可以的,总不能现在还是让前端启动配置一个和测试生产环境一样的 nginx 来调试吧。 现在前端由于是编译的,没法做到使用类似../../这种相对路径请求接口,但前端接口请求一定不能是完整地址待域名端口(类似 http://域名:端口/)这种,一定要是直接到根这种。 |
![]() | 53 azhangbing 2024-07-11 11:57:05 +08:00 ![]() 因为跨域限制是古早时候 浏览器的同源策略 那时候一般都放在同个域名,端口下的 很早很早了 |
54 yusf 2024-07-11 11:58:50 +08:00 ![]() 跨域是浏览器行为 |
![]() | 55 xiaochena 2024-07-11 11:59:45 +08:00 ![]() @bluicezhen Access-Control-Allow-Origin: * 就不能带 cookie 了哦 |
![]() | 56 0IuL7w7X5K2HJxZf 2024-07-11 12:02:30 +08:00 跨域的问题不只是原理,你以为理解了,MDN 那个文档看过无数遍了,但是每次和前端对接都会出现新的问题,xhr ,fetch ,axios ,不同的库对 cors 的使用方法和处理方式不同,烦人的很,而且现在的跨域限制的更多了,以前能行的办法突然发现某些情况下又不行了。 |
57 iOCZS 2024-07-11 12:04:43 +08:00 ![]() 人们制定了很多规则,但是又不善于记忆规则。 |
![]() | 58 encro 2024-07-11 12:04:52 +08:00 ![]() 讲点核心的: 首先,你得理解为什么浏览器要限制跨域: 1 ,比如我公司的静态 js 和图片,被某大流量网站直接引用了,我流量不直接被刷爆? 2 ,某域名直接 iframe 之类嵌套,或者引用我的资料,打着李逵额名号,其实是李鬼。 所以,浏览器限制了跨域请求。 问:那么,我们开发时,想要访问线上接口怎么办? 答:我们可以用 vite 之类 nodejs 的代理功能,通过代理访问线上接口,代理一词的意思是我们访问本地的接口,代理服务器通过本地程序(非浏览器)转发到线上接口。 问:如果我们确实有线上项目的跨域请求的需求怎么办? 答:我们可以在服务器设置 Access-Control-Allow-Origin ,将我们自己人加入白名单。 跨域,就是这么简单! |
60 bertonzh 2024-07-11 12:07:06 +08:00 ![]() 「我认为这是现在的前端脚手架提供的一个极其糟糕的功能」 你这个观点不对。 本地开发服务器会提供接口代理,它的一个重要的背景是: 世界上绝大多数网页服务,网页域名跟接口域名是一样的,也就是线上一般不会存在跨域问题。 开发工具做这个代理逻辑,仅仅是为了跟线上保持一致而已。 确实存在接口域名跟网页域名不一样的时候,但是这不应该是常态。因为即使处理了跨域的问题,还有三方 cookie 的问题等着你。 |
61 itakeman 2024-07-11 12:08:52 +08:00 via Android ![]() 前端的事情前端完成,别什么都麻烦后端 |
![]() | 62 AV1 2024-07-11 12:11:01 +08:00 ![]() @shadowyue 跨域请求,后端是有日志的。 而且如果是 GET 请求,在后端看来,甚至是一次成功的请求,它感知不到自己返回的结果被浏览器拦截了。 我们看到的“Access to fetch at 'xxxx' from origin 'xxxx' has been blocked by CORS policy”异常,是发生在接受返回值的阶段,而不是发请求的阶段: JS>浏览器>服务器>浏览器 >JS |
![]() | 63 shadowyue OP @bertonzh 原来如此,感谢你的回复。因为目前我这边的项目页面域名和服务端域名都是不相同的。 你这个说法也很有道理。 |
65 JKKK 2024-07-11 12:16:17 +08:00 ![]() 跨域本质上是个浏览器的安全策略,配合 HTTP 头信息安全的使用其他域名的资源 |
![]() | 66 shadowyue OP |
67 nevermoreluo 2024-07-11 12:18:03 +08:00 ![]() 我觉得核心逻辑是清楚地,但是实际务会因为一些框架或者代理之类的导致其他的异常的边界情况。并不能说这个问题就是这样。 我遇到过的边界情况包括但是不限于,运维同学 nginx 配置和研发同学代码框架冲突导致 header 被重复添加,旧的浏览器个别版本不支持 wildcard 等等等等。 这东西说难不难,但是实际业务中还是要跟着 response 去跟逻辑去处理或者规范框架配置。 |
![]() | 68 thoo61871 2024-07-11 12:19:56 +08:00 ![]() 后端转小会社全干,刚好上个月遇到这个问题学习了一下。那个帖子真的看得我一头冷汗。 |
69 Xu3Xan89YsA7oP64 2024-07-11 12:26:05 +08:00 ![]() 前端基本都知道跨域,但是能分清楚同源和同站的人真的很少,CSP 以及 cookie 的 sameSite 是同站 |
![]() | 70 brucexueth 2024-07-11 12:27:10 +08:00 ![]() “跨越了不同的域(名)想要去请求资源” 是有欠缺的,其实不只是域名,端口不同也算的。本质是因为同源策略,可以看看 https://zh.wikipedia.org/wiki/%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5 |
71 QlanQ 2024-07-11 12:27:49 +08:00 这几天折腾 canvas 加载 s3 源站的图片,折腾到现在都没弄好,就是提示 提示跨域了,s3 的我配置的没问题哇,别的图片都可以正常展示,就是 放到 canvas 就不行。。。 |
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 我,受我一拜。 |
73 Jinnrry 2024-07-11 12:38:27 +08:00 via Android ![]() 以前负责面试招人(3 到 5 年的后端),我发现最少一半以上的人讲不明白跨域,还有很多人讲不明白 cookie session ,但是这些人谈起 jvm 调优,谈起 java 源码却能头头是道 |
![]() | 74 iyaozhen 2024-07-11 12:41:44 +08:00 @bluicezhen 不行 你这样,如果想携带 cookie ,给* 不可以,必须确定的域名 |
![]() | 75 iyaozhen 2024-07-11 12:48:19 +08:00 ![]() 确实很多人不知道,可能还有另一部分原因,现在很多项目都是短平快,大家遇到问题总是希望有一个办法解决所有问题。不巧的是跨域这个问题很复杂,https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS 你没读 10 来遍是搞不清楚的。更悲剧的是,很多人都是看的二手资料,只知道了其中一部分,甚至是错的。 所以有了背 nginx 配置、jsonp 、Access-Control-Allow-Origin: * 等等片面的解决方案,毕竟具体问题具体分析很麻烦,反正这些都配置/用上,能跑就行 |
76 anjingdexiaocai 2024-07-11 12:49:51 +08:00 via Android ![]() 说的很细 |
![]() | 77 freezebreze 2024-07-11 12:50:25 +08:00 ![]() 这种问题 我只能说 what can i say |
![]() | 78 iyaozhen 2024-07-11 12:51:04 +08:00 ![]() 还有楼主说的 [浏览器会阻止给和页面地址不同的域名发请求] 其实也不完全是,就像前面说的,具体分析,有些请求是要等服务端返回,浏览器看一下 response header 才知道能不能跨域,这时候其实服务端已经处理成功返回了,只是返回的时候被浏览器拦截了。简单验证方法就是 Charles 抓个包,能看到 Charles 这边都是正常的。 |
![]() | 79 vincent7245 2024-07-11 12:55:25 +08:00 ![]() 我就不一样了,我从来没觉得自己是草台班子,我觉得我是公司里带领大家向前冲的大佬 (/狗头) |
![]() | 80 jsq2627 2024-07-11 13:00:53 +08:00 ![]() > 我认为这是现在的前端脚手架提供的一个极其糟糕的功能。 > 它把跨域这个完全由后端处理的问题默默的在开发环境处理掉了,并且还附加了接口地址改写的各种功能 强烈认同,见过无数初学者和草台班子搞不明白这个问题,最后索性直接在生产环境运行 vite dev |
![]() | 82 my3157 2024-07-11 13:12:23 +08:00 因为现在的框架都默认配置和处理了, 就像以前用 .net 框架的 webform 一样, 能写, 但不知道细节, 同样的问题还有 cookie , 另外现在浏览器的 localstorage/indexdb , 每次打开里面都是一坨乱七八糟的数据, 甚至敏感数据也直接往里面存 |
83 bytesfold 2024-07-11 13:14:02 +08:00 via iPhone ![]() 收藏了等于我会了 |
![]() | 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 |
![]() | 85 hukei 2024-07-11 13:17:42 +08:00 |
86 zackzergzeng 2024-07-11 13:20:23 +08:00 ![]() 所有问题都是因为用了浏览器这个全是窟窿眼的应用系统闹的 |
87 ooolooo 2024-07-11 13:29:35 +08:00 ![]() @Nosub 代理服务器不是服务器了? 前端写服务端代码就是前端问题啦? 这样的后端更可笑, 原来是你自己的文章啊, 前端大佬!!! |
88 skuuhui 2024-07-11 13:36:48 +08:00 ![]() 没有吧,术业有专攻,做过全栈开发的或者和前端对接频繁的知道很正常吧,一个纯后端开发强迫人家知道也没啥用,不知道也正常。但也不代表草布草台的吧,这玩意也不是多深奥东西说白了这个和 set-cookie ,302 都是一套浏览器规则罢了,说不定哪天来个 100%国产纯血浏览器还限制呢。 |
![]() | 89 Liam1997 2024-07-11 13:37:19 +08:00 ![]() @Nosub 你贴的第一个链接,就是开发模式下,前端脚手架启动一个 nodejs 服务器转发啊,和 OP 说的有区别么 |
90 LuckyLauncher 2024-07-11 13:37:51 +08:00 @Nosub 代理服务器和 Nginx 什么时候属于前端范畴了?浏览器什么时候能启动 Nginx 了 |
![]() | 91 shadowyue OP ![]() @Nosub #84 哥你真是让我汗流浃背 第一个帖子明显是和 vue 的脚手架一样是开发环境解决跨域的方案,你试试部署时候能用吗? 第二个帖子都上 nginx 了还算前端吗? 你真是给这个帖子提供了最佳素材 |
![]() | 92 Promtheus 2024-07-11 13:40:36 +08:00 这和前后端有啥关系 这不是常识吗。。一般后端都会写一些简单的前端代码的。 |
![]() | 93 poorcai 2024-07-11 13:41:37 +08:00 ![]() 哈哈哈哈,学习了 |
![]() | 94 wqhui 2024-07-11 13:41:43 +08:00 ![]() 东西太多了,没法全认真学这么细,知道怎么解决就好 |
![]() | 95 wildnode 2024-07-11 13:42:16 +08:00 ![]() 大约有 50% 的后端会掏出 postman 请求一下然后说我这没问题啊 大约有 30% 的后端会问你,CORS 是啥玩意,我加什么响应头? 大概只有 20% 是正常人 |
![]() | 97 shadowyue OP |
99 Nitsuya 2024-07-11 13:43:57 +08:00 ![]() 一样一样, 都是草台班子, 干了 11 年了,经常看同事写屎山,有时候说两句,有时候我都懒得说. 也不指望他们有啥长进, 毕竟总要有人干 CRUD 的代码. |
![]() | 100 Tyrant1984 2024-07-11 13:44:00 +08:00 ![]() 每个字我都认识,我真棒~ |