cors.Default()在生产环境会失败,因为它同时设置Access-Control-Allow-Origin:*和Access-Control-Allow-Credentials:true,而浏览器禁止该组合;启用凭据时必须指定具体域名列表且禁用通配符。

生产环境直接用 cors.Default() 就是埋雷——它等价于允许任意源带凭证访问,浏览器会直接拒绝请求。
为什么 cors.Default() 在生产环境会失败
这个快捷配置看似省事,实际会设置 Access-Control-Allow-Origin: * 和 Access-Control-Allow-Credentials: true 同时存在,而这是浏览器明确禁止的组合。只要前端代码里用了 credentials: 'include' 或设置了 withCredentials = true,请求就会被静默拦截,控制台只显示“CORS header ‘Access-Control-Allow-Origin’ cannot contain the wildcard ‘*’ when the request’s credentials mode is ‘include’”。
- 开发阶段可以用,但必须确认前端没发带 cookie 的请求
- 一旦启用了
AllowCredentials: true,AllowOrigins必须是具体域名列表,不能是"*" -
https://foo.com和https://www.foo.com是两个不同 origin,都要显式列出
正确配置 gin-contrib/cors 的最小必要参数
核心不是“全放开”,而是让响应头之间不冲突。关键在于 Origin 校验逻辑和凭证开关的配合。
-
AllowOrigins:填具体域名数组,例如[]string{"https://example.com", "https://app.example.com"};本地调试可加"http://localhost:8080" -
AllowCredentials:设为true仅当前端确实需要传 Cookie 或 Authorization header;否则设false,此时AllowOrigins才能用"*" -
AllowHeaders:至少包含"Content-Type"和前端实际发送的 header,比如"Authorization"、"X-Requested-With" -
ExposeHeaders:如果前端要读取响应里的自定义 header(如X-Total-Count),必须在这里显式声明
预检请求(OPTIONS)被 404 或 500 怎么办
Gin 默认不自动处理 OPTIONS 方法,中间件必须在路由注册前加载,且不能被其他中间件提前终止流程。
- 确保
router.Use(cors.New(...))在所有router.GET/POST之前调用 - 检查是否有其他中间件(如 JWT 鉴权)在 OPTIONS 请求上 panic 或返回错误——OPTIONS 请求不该触发业务逻辑校验
- 如果用了自定义路由组(如
v1 := router.Group("/api/v1")),CORS 中间件必须注册在 group 上,而不是只注册在 default router - 不需要手动写
router.OPTIONS路由;gin-contrib/cors内部已自动响应预检
前端仍报跨域,但响应头看起来没问题?查这几个点
浏览器控制台看到的响应头,未必是最终生效的那组。常见干扰来自 Nginx、CDN 或多层代理。
- 用 curl 检查原始响应:
curl -H "Origin: https://example.com" -I http://your-api.com/api/data,确认Access-Control-Allow-Origin值是否匹配且没被覆盖 - 如果用了 Nginx 反向代理,它可能删掉了后端 Set 的 CORS 头,需在 Nginx 配置里显式放行:
add_header 'Access-Control-Allow-Origin' '$sent_http_access_control_allow_origin' always; - Chrome 的“禁用缓存”选项只影响资源加载,不影响 OPTIONS 预检缓存;修改
MaxAge后要等缓存过期或清空浏览器 DNS + CORS 缓存 - 某些浏览器扩展(如隐私类插件)会主动屏蔽或改写 CORS header,可尝试无痕模式复现
最易忽略的是:同一个域名下,HTTP 和 HTTPS 被视为不同源;本地开发时 localhost 和 127.0.0.1 也是不同源——这些细微差异往往导致白名单漏配,而错误信息又不明确。


















