news 2026/10/7 8:35:30

一站式了解跨域问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一站式了解跨域问题

文章目录

  • 引言
  • 同源策略
  • 跨域问题如何产生?
  • 解决方案一:CORS(跨源资源共享)
    • 1. 简单请求(Simple Requests)
    • 2. 预检请求(Preflighted Requests)
    • 代码示例
      • Java (Spring Boot 示例)
      • Go (Gin 框架示例)
  • 解决方案二:反向代理
    • 集中管理与解耦
    • 安全性与架构优势
    • 架构示意图
  • 总结

引言

在平时的后台开发中,我们会经常遇到跨域问题,那么跨域问题到底是什么,怎么去解决跨域问题呢?今天我们就一起探讨一下。

同源策略

跨域问题本质上是由于浏览器的同源策略(Same-Origin Policy)引起的。

同源策略是浏览器的一个安全限制。它规定,一个源(Origin)的文档或脚本只能与同源的资源进行交互。

  • “源”由三个部分组成:协议(Protocol)、主机(Host/Domain)和端口号(Port)。
  • 如果请求的 URL 与当前页面的 URL 相比,任一部分不同,就被认为是跨源。
当前页面 URL目标 URL是否同源?跨源原因
http://a.com:8080/index.htmlhttp://a.com:8080/data.json是(全部相同)
http://a.com:8080/**https**://a.com:8080/否协议不同 (httpvshttps)
http://a.com:8080/http://**b.com**:8080/否主机不同 (a.comvsb.com)
http://a.com:8080/http://a.com:**9090**/**否端口不同 (8080vs9090)

同源策略的目的是保护用户安全和隐私,防止恶意网站通过浏览器脚本访问其他网站的敏感数据。

跨域问题如何产生?

当浏览器中的前端代码(如使用XMLHttpRequest或FetchAPI)尝试向一个不同源的服务器发起 HTTP 请求时,浏览器会拦截服务器返回的数据,导致请求失败(但在网络层面上,请求实际上已经发送到服务器并收到了响应)。

这就是我们在开发中常说的跨域报错,通常你会看到类似No 'Access-Control-Allow-Origin' header is present on the requested resource的错误信息。

解决方案一:CORS(跨源资源共享)

在本地开发测试阶段可以通过配置cors来解决跨域问题。

跨源资源共享(Cross-Origin Resource Sharing,CORS)是一种允许浏览器放宽同源策略限制的机制。它通过在服务器端设置特定的HTTP 响应头,来告知浏览器该服务器允许哪些源访问其资源。

CORS 主要分为两种请求模式:

1. 简单请求(Simple Requests)

如果请求同时满足以下所有条件,则被认为是简单请求:

  • 方法:只能是GET、POST、HEAD之一。

  • 请求头:只能包含少数几个安全的请求头(如Accept、Accept-Language、Content-Language、Content-Type等),且Content-Type只能是以下三种之一:

    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

工作流程:

  1. 浏览器直接发送请求,并在请求头中带上Origin字段,表明自己的源。
  2. 服务器收到请求后,如果允许跨源访问,则在响应头中加入Access-Control-Allow-Origin字段,指定允许的源(例如:Access-Control-Allow-Origin: http://client.com或Access-Control-Allow-Origin: *)。
  3. 浏览器检查响应头,如果发现Access-Control-Allow-Origin允许当前源,则将数据交给前端代码;否则,抛出跨域错误。

2. 预检请求(Preflighted Requests)

对于非简单请求(例如:使用了PUT、DELETE方法,或者设置了自定义请求头),浏览器会先发送一个使用OPTIONS方法的预检请求,以确定服务器是否安全。

工作流程:

  1. 浏览器发送OPTIONS预检请求:请求头包含:

    • Origin:当前源。
    • Access-Control-Request-Method:实际请求将使用的方法(如POST)。
    • Access-Control-Request-Headers:实际请求将携带的自定义请求头(如X-Custom-Header)。
  2. 服务器处理预检请求:服务器检查这些请求头,如果允许,则在预检请求的响应头中返回:

    • Access-Control-Allow-Origin:允许的源。
    • Access-Control-Allow-Methods:允许的方法。
    • Access-Control-Allow-Headers:允许的自定义请求头。
    • Access-Control-Max-Age:预检结果的缓存时间(秒)。
  3. 浏览器检查预检结果:如果预检通过,浏览器才会发送实际的 HTTP 请求(GET/POST/PUT/DELETE 等)。

  4. 服务器处理实际请求并返回数据(响应头中通常仍会包含Access-Control-Allow-Origin)。

代码示例

Java (Spring Boot 示例)

在 Spring Boot 中,你可以通过配置WebMvcConfigurer或在 Controller 上使用@CrossOrigin注解来解决:

// 方法一:全局配置 (推荐)@ConfigurationpublicclassCorsConfigimplementsWebMvcConfigurer{@OverridepublicvoidaddCorsMappings(CorsRegistryregistry){registry.addMapping("/**")// 匹配所有路径.allowedOrigins("http://your-frontend-domain.com")// 允许的源,可以设为 "*" 允许所有(不推荐用于生产).allowedMethods("GET","POST","PUT","DELETE","OPTIONS")// 允许的方法.allowedHeaders("*")// 允许所有请求头.allowCredentials(true)// 是否允许携带 Cookie.maxAge(3600);// 预检请求的缓存时间}}

Go (Gin 框架示例)

如果你使用 Gin 框架,可以借助第三方 CORS 中间件,例如github.com/gin-contrib/cors:

// Go 示例 (使用 Gin 框架和 gin-contrib/cors 中间件)packagemainimport("time""github.com/gin-contrib/cors""github.com/gin-gonic/gin")funcmain(){r:=gin.Default()// 配置 CORS 中间件r.Use(cors.New(cors.Config{AllowOrigins:[]string{"http://your-frontend-domain.com"},// 允许的源AllowMethods:[]string{"GET","POST","PUT","DELETE","OPTIONS"},AllowHeaders:[]string{"Origin","Content-Type","Authorization"},// 允许的请求头ExposeHeaders:[]string{"Content-Length"},// 允许前端访问的响应头AllowCredentials:true,// 允许携带 CookieMaxAge:12*time.Hour,}))r.GET("/ping",func(c*gin.Context){c.JSON(200,gin.H{"message":"pong",})})r.Run()}

解决方案二:反向代理

这是生产环境中最常用且推荐的方案。前端请求同源的代理服务器,由代理服务器转发请求给目标服务器。因为请求发生在服务器之间,不受浏览器同源策略限制。

当浏览器向代理服务器(例如http://api.frontend.com)发送请求时,由于前端页面和代理服务器是同源的,浏览器不会触发同源策略限制。代理服务器在收到请求后,再将其转发到后端服务(例如http://backend-service:8080)。服务器之间的通信不存在跨域限制

集中管理与解耦

将跨域配置、SSL/TLS 证书、负载均衡、限流、缓存等所有非业务性的公共配置,全部集中在反向代理层处理。

  • 后端服务解耦:后端服务(Java/Go)可以专注于业务逻辑,无需关心这些基础设施配置。
  • 配置统一:只需要在 Nginx 或 Gateway 上配置一次,适用于所有后端服务

安全性与架构优势

  • 隐藏真实服务地址:客户端只能看到代理服务器的地址,后端服务的真实 IP 和端口被隐藏,提高了安全性。

  • 更细致的访问控制:代理层可以更容易地实现基于路径的访问控制和限流

架构示意图

总结

解决跨域问题,在开发测试环境中,为了简单快捷我们可以使用cors。在生产部署环境中,强烈建议使用反向代理。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/6 10:16:14

终极AI平台wgai:零门槛构建国产化智能识别系统

终极AI平台wgai:零门槛构建国产化智能识别系统 【免费下载链接】wgai 开箱即用的JAVAAI在线训练识别平台&OCR平台AI合集包含旦不仅限于(车牌识别、安全帽识别、抽烟识别、常用类物识别等) 图片和视频识别,可自主训练任意场景融合了AI图像识别opencv、…

作者头像 李华
网站建设 2026/10/7 3:34:30

基于VUE的企业协同管理系统 [VUE]-计算机毕业设计源码+LW文档

摘要:随着企业规模的扩大和业务的复杂化,企业内部的协同工作效率成为影响企业竞争力的关键因素。本文介绍了一种基于VUE框架开发的企业协同管理系统,详细阐述了系统的需求分析、技术选型、架构设计、功能模块实现等内容。该系统涵盖了系统用户…

作者头像 李华
网站建设 2026/10/6 22:57:41

如何快速使用bandcamp-dl:命令行音乐下载工具的完整教程

如何快速使用bandcamp-dl:命令行音乐下载工具的完整教程 【免费下载链接】bandcamp-dl Simple python script to download Bandcamp albums 项目地址: https://gitcode.com/gh_mirrors/ba/bandcamp-dl Bandcamp-dl是一款功能强大的开源工具,专门用…

作者头像 李华
网站建设 2026/10/7 1:18:28

【Excel VBA 编程】第61讲:两种方法驾驭文本处理猛兽

VBA正则表达式中引入贪婪匹配与惰性匹配两种模式,本质上是为编程者提供控制匹配“粒度” 的关键工具。因此,理解并正确运用这两种模式,能够有效解决文本处理中常见的边界模糊问题,快速实现精准数据提取和文本分析贪婪匹配上一期我…

作者头像 李华
网站建设 2026/10/7 3:41:19

探索金领冠珍护源初的纯净世界:2025年健康奶粉新篇章

凌晨三点,看着小床上翻来覆去揉肚子的宝宝,我盯着奶粉罐上的成分表第N次叹气——胀气、便秘、最近还总爱抓耳朵……当妈后才懂,选奶粉哪是“随便买一罐”的事儿?每一个细微的消化不适、每一次免疫力“掉线”,都像一根针…

作者头像 李华
网站建设 2026/10/7 3:41:18

Solon 不依赖 Java EE 是其最有价值的设计!

Java 后端开发领域,Solon 作为一个后起之秀的微服务应用开发框架,正以其轻量、快速、高度灵活的特性获得越来越多的关注。与 Spring/Spring Boot 等早期框架诞生于 Java EE(现 Jakarta EE)的生态背景不同,Solon 从一开…

作者头像 李华