全栈开发中如何解决跨域问题?

考查重点:同源策略与跨域响应配置。后端 CORS 允许可信来源或反向代理统一同源;带凭证需匹配来源和凭证配置,不能靠前端关闭浏览器限制

本题目录

参考答案

核心回答

全栈开发中,常用两种方式解决浏览器跨域访问接口的问题:服务端配置 CORS,允许受信任的前端来源;或者通过反向代理,让页面和 API 对浏览器呈现为同源。 开发环境可以使用开发服务器代理,生产环境可以在网关统一转发和管理。

先明确什么是跨域:普通 HTTP URL 的源由协议、主机和端口组成。例如页面在 http://localhost:5173,接口在 http://localhost:8000,端口不同就是跨源;只改变路径则不会改变源。

同源策略主要限制网页脚本读取跨源响应等能力,并不是所有跨源请求都发不出去。部分请求可以直接到达服务端,只是响应不能被脚本读取;需要预检的请求则会先发 OPTIONS,预检未通过时,实际请求通常不会发出。因此,遇到问题要看浏览器控制台和 Network,区分是预检失败、响应头不匹配,还是接口本身报错。

两种方案如何落地

**服务端 CORS**适合前后端确实需要使用不同来源的场景。服务器根据请求的 Origin 匹配允许列表,在响应中返回相应的 Access-Control-Allow-Origin,并允许实际需要的方法和请求头。如果配置了多个允许来源,应匹配后返回本次允许的一个来源,不能把多个域名直接拼成该响应头,也不能无条件回显任意 Origin。

例如跨源提交 JSON,或者携带 Authorization 请求头时,浏览器通常需要预检。服务器应正确处理 OPTIONS,核对来源、目标方法和请求头,返回成功状态及对应 CORS 响应头。预检通过后,实际响应仍然需要正确的 CORS 头;只给 OPTIONS 加头不够。需要让脚本读取自定义响应头时,再通过 Access-Control-Expose-Headers 暴露。

如果按不同 Origin 动态返回不同响应头,应同时正确设置 Vary: Origin,让缓存区分来源。CORS 可以由应用中间件或网关负责,但应明确由哪一层统一处理,避免代理和应用重复添加后产生冲突。

同源反向代理适合统一入口的部署。比如浏览器始终访问 https://app.example.com/api/...,由网关把 /api 转发给内部后端;页面与接口在浏览器看来协议、主机和端口都相同。服务器之间的转发不受浏览器同源策略限制。

开发时也是同样思路:前端向当前开发服务器的 /api 发请求,再由开发服务器转发。前端如果仍然直接请求另一个端口,就没有经过这个代理。开发代理配置也不会自动变成生产网关配置,上线时仍需安排对应的入口和路由。

带登录 Cookie 时要额外检查什么

跨源请求需要携带 Cookie 时,前端要启用相应的凭据选项,例如 Fetch 的 credentials: "include";服务端返回匹配的具体来源和 Access-Control-Allow-Credentials: true。此时 Access-Control-Allow-Origin: * 不能满足浏览器的校验,即使这次恰好没有可发送的 Cookie,也不能用通配来源配合 include 模式。

CORS 放行后,Cookie 是否实际发送,还受 Domain、Path、SameSite、Secure 和浏览器第三方 Cookie 策略等约束。跨源与跨站也不是同一个判断,不能看到跨域报错就一律修改 SameSite。

正常的 CORS 预检不携带业务登录 Cookie,因此鉴权链路不能简单地把预检当作需要登录的业务调用而直接拦掉;实际业务请求仍然需要鉴权。手动添加 Bearer Token 到 Authorization,则还要允许这个请求头,不能把它与浏览器自动携带 Cookie 混为一谈。

深度研搜教程的 FastAPI 服务使用 CORSMiddleware 支持前后端分端口联调。对于带 Cookie 的正式站点,应明确列出允许的前端来源,并按实际请求配置方法、请求头和凭据选项,不能把宽泛的本地联调配置直接当作完整登录方案。

跨域报错怎么排查

  1. 核对实际地址。 看页面 Origin、最终请求 URL、端口、协议和重定向目标,确认是否经过预期代理。DNS、证书、混合内容和网络失败也可能伴随类似的请求错误,先看具体报错。
  2. 看预检。 如果有 OPTIONS,检查是否被路由、网关或鉴权拦截,状态是否成功,允许的来源、方法和请求头是否匹配。预检结果可能被浏览器缓存,不一定每次都有 OPTIONS。
  3. 看实际响应。 检查成功及 401、403、500 等错误响应是否带有正确的 CORS 头,是否被代理覆盖或重复添加。否则后端的真实错误可能被浏览器表现为 CORS 失败。
  4. 再看登录与缓存。 核对凭据模式、Cookie 的发送条件,以及按 Origin 变化的响应是否正确区分缓存。

常见追问

为什么 Postman 或后端调用正常,浏览器却失败?

浏览器会执行同源策略和 CORS 校验,普通服务端 HTTP 客户端不替浏览器执行这些规则。命令行请求可以帮助核对响应头,但接口可调用不代表网页脚本一定可读取响应。

前端设置 no-cors 能解决吗?

不能把它当作读取跨源 API 的方案。跨源请求在 no-cors 模式下还会受到方法和请求头限制,成功返回的通常是不透明响应,脚本无法按正常 API 响应读取状态、头和正文。正确做法仍是配置 CORS 或通过同源入口转发。

CORS 能代替鉴权或防 CSRF 吗?

不能。CORS 控制浏览器向网页脚本共享响应的条件,不负责证明调用者有业务权限,也不能阻止所有跨站请求到达服务端。接口仍需鉴权,涉及 Cookie 登录和状态变更时仍需设计相应的 CSRF 防护。

对应教程

参考资料

  • 国内:阮一峰:浏览器同源政策及其规避方法:采用协议、主机和端口的示例,解释正文中同源判断的三个要素以及路径变化为何不改变源。
  • 国内:阮一峰:跨域资源共享 CORS 详解:参考简单请求、预检与正式响应的交互,说明正文中 Origin、允许来源、方法和请求头如何匹配;采用范围以当前标准核对的规则为准。
  • 国内:阿里云 API 网关:配置跨域策略:借鉴路由级策略及配置项,解释正文中网关的来源匹配、允许请求头、暴露响应头与凭据选项的区别。
  • 国外:MDN:Cross-Origin Resource Sharing:参考请求分类、凭据、第三方 Cookie 与响应头的说明,展开正文对预检、Cookie 未发送和按来源变化的缓存问题的排查。
  • 国外:WHATWG:Fetch Standard:CORS 协议、凭据组合、预检响应、不透明响应和 HTTP 缓存规则,核验通配来源、实际错误响应及 no-cors 的行为边界。

相关面经

5 篇

靖安科技

后端工程师(RAG/Agent 项目)
秋招一面
查看原面经 →
什么是跨域

字节跳动

前端开发工程师
一面
查看原面经 →
浏览器跨域问题,解决方案

汇川技术

AI 全栈开发工程师
实习一面
查看原面经 →
做项目有没有遇到跨域问题
解决跨域的方法有哪些,你使用哪些

英迈软件

后端开发工程师
查看原面经 →
跨域问题怎么处理的

要务科技

后端开发工程师(AI 应用)
一面
查看原面经 →
你开发的时候是全栈是吧,跨域问题怎么解决

相关题目

4 题