应使用 gin-contrib/cors 而非手写 header,因其自动处理 OPTIONS 预检、校验 origin 白名单、注入 expose headers 且兼容 Gin 中间件链;需在 r.Use() 中前置注册,生产环境禁用 cors.Default(),须显式配置 AllowCredentials、AllowOrigins 等,并确保 Nginx 透传 CORS header。

直接用 gin-contrib/cors,别手写 header
手写 c.Header() 看似简单,但预检(OPTIONS)响应容易漏、Allow-Credentials 和 * 冲突会静默失效、header 设置时机错一次就白配——这些坑在真实项目里反复出现。官方维护的 gin-contrib/cors 封装了完整流程:自动响应 OPTIONS、校验 origin 白名单、按需注入 expose headers,且和 Gin 的中间件链深度兼容。
-
go get github.com/gin-contrib/cors安装即可,无其他依赖 - 必须在
r.Use(...)中注册,且要在任何路由定义 之前,否则中间件不生效 - 若需携带 cookie 或
Authorization,禁止用AllowAllOrigins = true,必须显式列出域名,例如[]string{"https://myapp.com", "http://localhost:3000"} - 动态 origin(如从数据库查白名单)需自定义
AllowOriginFunc,不能依赖默认配置
cors.Default() 适合开发,上线前必须改配置
cors.Default() 默认允许所有 origin、所有方法、暴露基础 header,开发阶段能快速跑通,但上线后等于裸奔:它隐式禁用 AllowCredentials,且不设 MaxAge,每次请求都触发预检,增加延迟。
- 生产环境必须用
cors.New(config)显式控制行为 -
config.AllowCredentials = true时,config.AllowOrigins不能含"*",否则浏览器直接拒收响应 -
config.ExposeHeaders要列出前端 JS 实际要读的字段,比如"X-Total-Count"或"New-Token",没列的即使后端返回了也拿不到 -
config.MaxAge建议设为12 * time.Hour,减少重复预检
Nginx 后面跑 Gin?必须透传 CORS header
Gin 返回了正确的 Access-Control-Allow-Origin,但浏览器仍报错?大概率是 Nginx 拦截或覆盖了 header。Nginx 默认不透传自定义响应头,尤其当配置了 add_header 时,还会清空上游已设的 header。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- 确保 Nginx 配置中包含:
add_header 'Access-Control-Allow-Origin' '$sent_http_access_control_allow_origin' always;(用$sent_http_*变量透传 Gin 原始 header) - 禁用
add_header的继承行为:在 location 块加add_header ... always,否则子块会丢掉父块的 header - OPTIONS 请求不能被 Nginx 直接返回 204,必须透传给 Gin 处理,否则预检失败
- 检查 Nginx error log,常见错误是
upstream sent no valid HTTP/1.0 header,说明 upstream(Gin)提前写了 body 导致 header 无法再设
带凭证的请求失败?先确认三件事
前端发请求带了 withCredentials: true,后端也设了 AllowCredentials: true,但依然跨域失败——问题往往不在 Gin 本身。
立即学习“go语言免费学习笔记(深入)”;
- 前端 origin 必须是完整协议+域名+端口,
http://localhost:3000和http://127.0.0.1:3000是不同源,白名单要都写上 - Cookie 的
SameSite属性必须为Lax或None,且Secure标志在 HTTPS 下才允许设为None - Gin 中间件顺序不能错:CORS 中间件必须在
Recovery、Logger等之前注册,否则 panic 时 header 已写入,CORS 头无法补上
实际部署时最常被忽略的是 Nginx 透传逻辑和 origin 白名单的精确匹配——哪怕多一个斜杠、少一个协议,CORS 就会静默失效。

















