当前位置: 首页 > news >正文

CORS跨域解决终极指南

0. 同源策略详解

同源策略(Same-Origin Policy)是浏览器最核心的安全策略之一,它限制了来自不同源的文档或脚本如何与当前文档进行交互。

解决方法:后端需要实现 CORS 支持,这正是这节要详细讲解的内容。

1.CORS

摘要:本文详细介绍了 CORS(跨域资源共享)的原理、限制及解决方案。首先解释了同源策略的概念及其对前后端分离架构的影响,然后阐述了 CORS 的工作机制,包括预检请求和响应头配置。重点讲解了如何使用 Go 语言的 Gin 框架配合cors中间件实现跨域访问控制,包括各种配置选项的含义和用法。最后通过完整的代码示例展示了如何在实际项目中配置 CORS 中间件和处理跨域请求。

判断是否是同一个源:协议、域名、端口。

同源访问是浏览器的核心安全策略。

当前后端分离, 前后端是不同的源,浏览器先访问前端,当前端再去访问后端时,会触发浏览器的同源访问策略,因为前后端此时不是同一个源,此时请求会发出,但响应被浏览器拦截,发现不同源后,拒绝把响应返给前端。

①浏览器会对跨域做出哪些限制?

例如:[源A]和[源B]是非同源的,则浏览器会有如下限制:

  1. DOM访问限制:源A的脚本不能读取和操作源B的DOM
  2. Cookie访问限制:源A不能访问源B的cookie
  3. 响应数据限制:源A可以给源B发请求,但是无法获取源B的请求(这个是主要要解决的问题,也是遇到最多的问题 )

②CORS 概述 CORS 全称: Cross - Origin Resource Sharing
(跨域资源共享),是用于控制浏览器校验跨域请求的一套规范,服务器依照 CORS 规范,添加特定响应头来控制浏览器校验,大致规则如下:

  • 服务器明确表示拒绝跨域请求,或没有表示,则浏览器校验不通过
  • 服务器明确表示允许跨域请求,则浏览器校验通过 备注说明:使用 CORS 解决跨域是最正统的方式,且要求服务器是"自己人",因为使用cors解决跨域是要改动服务器代码。

③解决思路:当服务器接收到探测options请求后,如果请求的源在白名单里,则在响应头里加上Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers
等关键参数,浏览器拦截响应数据,看到有这些响应头,就知道要放行,于是客户端就得到了数据,否则,客户端得不到数据。

我们可以添加一个中间件,对每个请求的执行上面的操作,第三方库cors实现了这点,我们只需要配置参数就可以了,如下

Config是配置cors中间件时的所有可选项

cors.Config{AllowAllOrigins:false,//true标识允许所有域名AllowOrigins:nil,//允许的域名列表AllowOriginFunc:nil,//自定义函数来动态判断是否允许某个域名AllowOriginWithContextFunc:nil,//同上,但是传入了gin.ContextAllowMethods:nil,//允许使用的HTTP方法,未设置时默认简单方法集合:GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS。AllowPrivateNetwork:false,//是否允许私有网络(如局域网 IP)访问AllowHeaders:nil,//非简单请求时,允许的请求头(如 X-Custom-Header、 Authorization)中,允许客户端实际发送的头列表。AllowCredentials:false,//是否允许携带凭证:Cookie、HTTP认证(token)、客户端证书等ExposeHeaders:nil,//指定哪些响应头能被前端代码读取MaxAge:0,//预检请求(OPTIONS)的结果可以被缓存多久AllowWildcard:false,//是否支持通配符匹配域名(如 http://*.example.comAllowBrowserExtensions:false,CustomSchemas:nil,AllowWebSockets:false,AllowFiles:false,//是否允许 file:// 协议OptionsResponseStatusCode:0,}

[!CAUTION]

哪些是需要在ExposeHeaders中指明的?哪些不需要?

默认情况下,浏览器只允许前端 JavaScript 读取以下6 个简单响应头

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

除此之外的所有响应头,如果你希望前端(例如通过fetchXMLHttpRequest)能读取到,都必须在 CORS 配置的ExposeHeaders显式列出

常见需要显式暴露的响应头举例

响应头常见用途
Authorization登录后后端返回的 Bearer token 有时会放在响应头中
X-Total-CountREST API 返回数据总数(分页用)
X-Request-Id用于请求追踪和调试
X-Pagination-PageX-Pagination-Limit自定义分页信息
Content-Disposition文件下载时的文件名
Retry-After限流时告知客户端多久后重试
Location重定向或创建资源时返回新 URL
任何自定义头(如X-User-IdApp-Version业务需要的额外信息

代码示例

typeteacherstruct{Namestring`json:"name"`Ageint`json:"age"`Sexstring`json:"sex"`}varteachers=[]teacher{{"小红",12,"女"},{"小X",14,"男"},{"小A",13,"女"},}funcverifAuth(authorizationstring)bool{ifauthorization==""{returnfalse}returntrue}funcmain(){//导入日志log1:=logs.Logger1// 2. 初始化 Ginr:=gin.Default()// 3. 设置 CORS 中间件(全局生效,白名单来自配置)r.Use(cors.New(cors.Config{AllowOrigins:[]string{"http://localhost:63342","https://www.u2tool.com"},AllowMethods:[]string{"POST","GET","PUT","PATCH","DELETE","HEAD","OPTIONS"},AllowHeaders:[]string{"set-cookie","Authorization","Content-Type"},AllowCredentials:true,ExposeHeaders:[]string{"authorization"},MaxAge:1*time.Minute,}))// 4. 只有登录才能访问的业务(完全不需要写任何 CORS 代码)r.GET("/api/user",func(c*gin.Context){authorization:=c.GetHeader("authorization")ifverifAuth(authorization)==false{log1.Error("authorization 是空")c.JSON(http.StatusUnauthorized,gin.H{})return}log1.Info("获取到了token=",authorization)c.JSON(http.StatusOK,gin.H{"code":200,"data":teachers,"message":"请求成功"})})//登录r.POST("/api/order",func(c*gin.Context){vartoken="fake_abc123DEF456GHI789JKL0MNOpqrSTUvwxYZ"c.Header("Authorization",token)c.JSON(http.StatusOK,gin.H{"code":200,"data":teachers,"message":"请求成功"})})// 5. 启动服务r.Run(":8080")}

2.凭证

有三种:token、cookie、TLS(少见,用于双向TSL验证)

Cookie 与 Token的核心区别

特性Cookie(自动发送)Token(手动携带)
发送方式浏览器自动附加到请求的Cookie头中,前端无需写代码前端需要手动从存储(localStorage/sessionStorage)读取并设置Authorization: Bearer <token>
跨域限制默认会跨域发送(同源策略)。要跨域需配置withCredentials: true且后端AllowCredentials: true跨域时同样需要后端 CORS 支持Authorization头(在AllowHeaders中),但前端可手动添加该头
存储位置由浏览器管理,可通过HttpOnly禁止 JS 读取(防XSS)前端代码可控(localStorage/sessionStorage),易受 XSS 攻击
CSRF 风险存在 CSRF 风险(恶意站点利用已保存的 Cookie 发起请求),需用SameSite、CSRF Token 等防护无(因为攻击者无法读取 token 并手动添加到Authorization头)
移动端/非浏览器不支持(因为无浏览器自动管理 Cookie)广泛支持,token 可明文发送

cookie流程:

  1. 用户登录成功,服务器返回:

    Set-Cookie: sessionId=abc123; Path=/; HttpOnly; Secure; SameSite=Lax
  2. 浏览器保存这个 Cookie。

  3. 之后用户访问同域的任何页面、API(图片、AJAX等),浏览器自动加上:

    Cookie: sessionId=abc123
  4. 服务器收到后就知道是同一个用户

http://www.zskr.cn/news/1533194.html

相关文章:

  • 从Jekyll到Hugo:hugo-theme-cleanwhite让博客迁移变得简单
  • SolidWorks第四部分_直接实体建模特征5_实体阵列与镜像
  • PLX-DAQ串口数据采集:Excel实时接收与Arduino通信协议详解
  • 海南自贸港文旅版图:头部企业如何共绘发展新蓝图? - 品牌2026
  • Multisim 14.3安装部署全攻略:从网盘资源获取到系统环境配置
  • RuoYi-Vue:42k Star 的 Java 快速开发框架,别再从零搭后台了
  • 2026年儿童乐园游乐设备生产厂哪家合作案例多 - 工业设备
  • 3分钟学会FancyZones:让Windows窗口管理变得像拼积木一样简单
  • AI模型训练中的成本控制与算力预算规划策略
  • MSC8251以太网与SPI接口配置实战:从寄存器到调试全解析
  • Yakit/Yaklang 国密算法支持详解
  • Windows 11硬件限制绕过完整方案深度解析
  • 奇异矩阵:数据科学中必须读懂的线性代数诊断信号
  • 2026考场防作弊设备选购指南:中高考手机信号屏蔽仪哪家强?实战案例与厂商深度评测 - 优质品牌商家
  • 2026年自贡中专择校指南:如何从就业、升学、管理三大维度选中专?附多校实测分析 - 优质品牌商家
  • 宏科印业推荐哪家?综合对比与评价 - 工业品网
  • Superpowers工程化实践:AI编程的质量门禁与开发流水线
  • Gemini 3.1原生协同:谷歌AI如何重构操作系统级交互
  • 如何选择靠谱的Acetron GPPOMC供应商?价格指南 - 工业品网
  • NoC组件之Router微架构解析(四)仲裁
  • 多相机兼容驱动方案:从抽象接口到工业实践
  • OBS多平台直播插件:3步实现YouTube、Twitch、B站同步推流
  • Python两位小数处理:四舍五入、银行家舍入与decimal精度实战
  • AgentGPT与AutoGPT选型指南:自主代理落地的工程决策逻辑
  • VSCode+Qwen3本地编程助手:零数据出境的AI编码实践
  • 打破苹果生态壁垒:3步让Windows电脑变身专业AirPlay接收器
  • 三相异步电动机原理、选型、控制与维护实战指南
  • 如何用MetaboAnalystR 4.0实现终极LC-MS代谢组学分析
  • DeepSeek V4 API双模型架构解析:百万上下文如何成为开发基础设施
  • ReWoo架构:解耦推理与观测的大模型工作流重构