You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Gin框架中为单个路由配置CORS权限?

Gin 单个端点配置指定来源CORS

不用依赖全局CORS中间件,直接给不同路由绑定自定义的CORS处理逻辑就能实现你的需求。以下是具体实现方式:

1. 定义不同的CORS中间件

分别实现允许所有来源、仅允许google.com访问的两个中间件,手动处理CORS响应头和预检请求:

import "github.com/gin-gonic/gin"

// 允许所有来源的CORS中间件
func allowAllCORS() gin.HandlerFunc {
    return func(c *gin.Context) {
        c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
        c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
        c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")

        // 处理OPTIONS预检请求
        if c.Request.Method == "OPTIONS" {
            c.AbortWithStatus(204)
            return
        }

        c.Next()
    }
}

// 仅允许google.com访问的CORS中间件
func allowGoogleCORS() gin.HandlerFunc {
    return func(c *gin.Context) {
        origin := c.GetHeader("Origin")
        // 根据实际需求调整Origin匹配规则,比如包含子域或不同协议
        allowedOrigins := []string{"https://google.com", "https://www.google.com"}
        isAllowed := false
        for _, allowed := range allowedOrigins {
            if origin == allowed {
                isAllowed = true
                break
            }
        }

        if !isAllowed {
            c.AbortWithStatusJSON(403, gin.H{"error": "Forbidden origin"})
            return
        }

        c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
        c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
        c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")

        if c.Request.Method == "OPTIONS" {
            c.AbortWithStatus(204)
            return
        }

        c.Next()
    }
}

2. 给路由绑定对应中间件

将允许所有来源的中间件绑定到/data和/ping,限制来源的中间件单独绑定到/scrape:

func main() {
    r := gin.Default()

    // 绑定允许所有来源的路由组
    publicRoutes := r.Group("/")
    publicRoutes.Use(allowAllCORS())
    {
        publicRoutes.GET("/data", func(c *gin.Context) {
            c.JSON(200, gin.H{"data": "public accessible data"})
        })
        publicRoutes.GET("/ping", func(c *gin.Context) {
            c.JSON(200, gin.H{"message": "pong"})
        })
    }

    // 单独给/scrape绑定限制来源的中间件
    r.GET("/scrape", allowGoogleCORS(), func(c *gin.Context) {
        c.JSON(200, gin.H{"result": "scraped content"})
    })

    r.Run(":8080")
}

注意事项

  • 注意Origin的匹配规则:浏览器发送的Origin头会包含完整协议(如https://)和域名,所以要确保匹配的字符串和实际请求一致,也可以根据需求用字符串包含、正则等方式扩展匹配逻辑。
  • 预检请求(OPTIONS)必须单独处理,返回204状态码,否则浏览器会拦截后续请求。

内容的提问来源于stack exchange,提问作者xilaluna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 11:01:32