当前位置: 首页 > 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.jsqmd.com/news/1021346/

相关文章:

  • 从Jekyll到Hugo:hugo-theme-cleanwhite让博客迁移变得简单
  • Claude架构升级:模型路由层如何被编译时静态图推断取代
  • ChatGPT-4o不是升级,是服务权限切换
  • SolidWorks第四部分_直接实体建模特征5_实体阵列与镜像
  • PLX-DAQ串口数据采集:Excel实时接收与Arduino通信协议详解
  • 2026年四川挤塑板选购实战指南:从材质到工艺,手把手教你挑对保温材料! - 优质品牌商家
  • AI编程代理的过程记忆系统:用TypeScript与Shell构建可审计工程知识库
  • 2026兰州户外亮化工程公司怎么选?7家甘肃市场服务商综合解析 - 优质品牌商家
  • 基于CD4046的锁相环追频电路:从原理到调试的完整指南
  • Proface GP-Pro EX V4.09汉化包:官方安装、避坑指南与本地化实践
  • MPC860 SMC串口控制器:从原理到实战的深度配置指南
  • 2026年新疆移动厕所选购指南:哪些品牌质量可靠?岗亭、环保厕所厂家实测分析 - 优质品牌商家
  • AI辅助MRI诊断:从影像特征到临床决策的七步落地实践
  • 电动直升机地面测试:核心参数范围与安全调试指南
  • 终极指南:如何用NewJob智能插件提升求职效率300%
  • AI大模型到底是什么:从认知原理到零代码落地指南
  • 爬虫转大模型:信息采集能力如何变成 AI 竞争力:写进简历前要补的工程证据
  • 解锁WPF开发新境界:用Extended WPF Toolkit打造专业级桌面应用
  • 告别Visio破解:专业图表绘制的合规替代方案全解析
  • 国产大模型API兼容迁移实战:从协议适配到高性能部署
  • Multisim 14.3安装部署全攻略:从网盘资源获取到系统环境配置
  • 海南自贸港文旅版图:头部企业如何共绘发展新蓝图? - 品牌2026
  • 2026年深圳整厂回收品牌怎么选?多维度实测与行业趋势分析 - 优质品牌商家
  • Kimi K2.6长程编码能力解析:13小时不中断的工程级AI协作者
  • 笔记本电脑电池图标出现红叉的全面诊断与修复指南
  • Nginx学习与应用
  • OpenClaw离线智能体实战:Windows/CentOS本地AI工作站全栈部署
  • 代码AI率:人机协同编程时代的效率与质量平衡之道
  • RuoYi-Vue:42k Star 的 Java 快速开发框架,别再从零搭后台了
  • 2026年信息网络安全等级保护二级等保申请全解析:哪些服务商值得关注? - 优质品牌商家