gin-contrib/cors 配置 allowcredentials: true 时,alloworigins 不得含 "*",须显式指定或用 alloworiginfunc 动态校验;options 预检必须由中间件拦截并立即返回 204,且中间件注册须在路由前。

gin-contrib/cors 配置必须显式指定 AllowOrigins 列表
AllowCredentials: true 时,AllowOrigins 不能含 "*",这是浏览器强制限制。一旦同时返回 Access-Control-Allow-Origin: "*" 和 Access-Control-Allow-Credentials: "true",响应会被静默丢弃,前端卡在 pending 状态,控制台不报错也不重试。
开发环境可硬编码为:[]string{"http://localhost:3000", "http://127.0.0.1:3000"};生产环境必须用 AllowOriginFunc 动态校验,否则无法支持灰度域名、ngrok 临时调试地址或子域名多租户。
- 校验前先用
url.Parse(origin)检查 scheme 是否为https或http,拒绝data:、file:等非法协议 -
https://example.com和https://example.com/是两个不同 origin,比对前需统一去除末尾斜杠 - 子域名通配(如
"*.example.com")不被标准 CORS 支持,gin-contrib/cors也不处理,得自己用strings.HasSuffix或正则实现
OPTIONS 预检必须由中间件拦截并立即返回 204
gin-contrib/cors 默认不拦截 OPTIONS 请求(OptionsPassthrough: true),若下游路由没注册 OPTIONS 方法,请求直接 404,前端只显示模糊的 “CORS error”。而 gorilla/handlers.CORS() 默认拦截并返回 204,更省心,但要注意别在下游 handler 里重复挂 CORS 中间件,否则响应头写两次会触发 Go 的 http: multiple response.WriteHeader calls panic。
手写中间件时,r.Method == "OPTIONS" 分支必须:w.WriteHeader(http.StatusNoContent) 后立刻 return,不能调用 c.Next() 或任何业务逻辑。
- 所有 CORS 头(包括
Access-Control-Allow-Origin)必须在WriteHeader前设置,否则无效 - 若需暴露自定义响应头(如
X-Total-Count),必须显式设Access-Control-Expose-Headers - 加了
AllowCredentials: true后,务必同步设Vary: Origin,否则 CDN 可能缓存错误的响应头
中间件注册顺序决定 CORS 是否生效
Gin 的中间件必须在任何路由注册前调用 r.Use(),否则 OPTIONS 请求根本进不到中间件——比如你先写了 r.POST("/api/login", loginHandler),再 r.Use(corsMiddleware),那 OPTIONS /api/login 就会 404,因为路由没声明该方法,中间件压根没机会执行。
正确顺序是:r := gin.Default() → r.Use(cors.New(...)) → 再注册所有 r.GET/r.POST 等路由。
- 如果用了
gin-contrib/cors的DefaultConfig,它内部默认允许所有方法和常见 header,但依然不解决AllowCredentials和*冲突问题 - 不要在 handler 里手动
c.Header("Access-Control-Allow-Origin", ...),容易漏OPTIONS或写错时机 - 网关层(如 AWS API Gateway、Kong)做 CORS 更可靠,Gin 层只做兜底;微服务架构中,跨域应统一收口,避免每个服务各自配置
Go 版本与模块初始化影响 CORS 行为
go version 必须 ≥ go1.18,否则 go mod 默认行为异常,可能让 gin-contrib/cors 的泛型依赖解析失败,或导致 go get 下载到不兼容版本。
go mod init 后,CORS 配置必须放在网关或入口 HTTP handler 层,不能塞在某个业务 handler 里——跨域是协议层约束,不是业务逻辑的一部分。
- PATH 冲突时优先使用官方解压路径:
/usr/local/go/bin(macOS/Linux)或C:\Go\bin(Windows) - 运行
which go或where go查多个 go 二进制,删掉 SDK 管理器装的旧版(如~/sdk/go1.17.5) -
rs/cors和gorilla/handlers都要小心AllowedOrigins类型:前者是[]string,后者是handlers.AllowedOrigins([]string{...})函数调用,写错语法会编译不过
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











