Gin框架gin-contrib/cors中间件与Group()搭配失效问题
Gin路由组中gin-contrib/cors中间件失效的解决方案
问题现象
- 直接在Gin根路由器上使用
gin-contrib/cors中间件时,所有路由的CORS响应头正常返回 - 用
r.Group("/api")创建路由组后,组内所有路由均丢失access-control-allow-origin响应头,中间件完全失效 - 手动设置响应头或自定义极简CORS中间件(如下)可正常工作
func CORS() gin.HandlerFunc { return func(ctx *gin.Context) { ctx.Header("access-control-allow-origin", "*") ctx.Next() } }
- 尝试过在根路由器、路由组单独或同时挂载
cors.Default(),均无效果;仅将路由直接绑定到根路由器时中间件才生效
原因分析
cors.Default()的默认配置对预检请求(OPTIONS)的路径匹配逻辑存在局限性,当请求路由属于分组路径时,中间件无法正确匹配并处理预检请求,导致CORS头未被设置。而自定义中间件因为逻辑简单,直接对所有请求设置头,不受路由组匹配规则影响。
解决方案
放弃使用cors.Default(),改用自定义CORS配置,明确指定允许的源、方法、请求头,确保中间件能覆盖路由组内的所有请求(包括预检请求)。
方案1:根路由器挂载自定义CORS中间件
package main import ( "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" "time" ) func main() { r := gin.Default() // 自定义CORS配置,生产环境建议将AllowOrigins替换为具体信任域名 corsConfig := cors.Config{ AllowOrigins: []string{"*"}, AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, AllowHeaders: []string{"Origin", "Content-Type", "Authorization"}, ExposeHeaders: []string{"Content-Length"}, AllowCredentials: true, MaxAge: 12 * time.Hour, } // 根路由器应用中间件,所有路由组自动继承 r.Use(cors.New(corsConfig)) apiRouter := r.Group("/api") apiRouter.GET("/record", func(ctx *gin.Context) { ctx.JSON(200, gin.H{"status": "ok", "data": "record data"}) }) r.Run("127.0.0.1:3000") }
方案2:仅在路由组挂载自定义CORS中间件
package main import ( "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" "time" ) func main() { r := gin.Default() apiRouter := r.Group("/api") // 为目标路由组单独配置CORS corsConfig := cors.Config{ AllowOrigins: []string{"*"}, AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, AllowHeaders: []string{"Origin", "Content-Type", "Authorization"}, AllowCredentials: true, MaxAge: 12 * time.Hour, } apiRouter.Use(cors.New(corsConfig)) apiRouter.GET("/record", func(ctx *gin.Context) { ctx.JSON(200, gin.H{"status": "ok", "data": "record data"}) }) r.Run("127.0.0.1:3000") }
验证方式
用curl发送预检请求测试:
curl -X OPTIONS http://127.0.0.1:3000/api/record \ -H "Origin: http://your-frontend-domain.com" \ -H "Access-Control-Request-Method: GET"
查看响应头,确认access-control-allow-origin已正确设置。
内容的提问来源于stack exchange,提问作者Zhou Xudong
相关产品推荐
相关产品推荐

