【问题标题】:Go gin framework CORSGo gin 框架 CORS
【发布时间】:2015-06-07 17:37:26
【问题描述】:

我正在使用 Go gin 框架 gin

func CORSMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        c.Writer.Header().Set("Content-Type", "application/json")
        c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
        c.Writer.Header().Set("Access-Control-Max-Age", "86400")
        c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
        c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, X-Max")
        c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")

        if c.Request.Method == "OPTIONS" {
            c.AbortWithStatus(200)
        } else {
            c.Next()
        }
    }
}

我得到了状态码:200 OK,但是在 OPTIONS 请求之后没有任何反应。 看起来我错过了什么,但我不明白我哪里错了。

有人可以帮助我吗?

【问题讨论】:

    标签: go frameworks cors preflight go-gin


    【解决方案1】:

    我花了大约一个小时来了解为什么互联网上的某些示例有效,而有些则无效。所以我明白了 - 行顺序很重要,首先你应该使用配置然后声明你的端点,但不是相反的方式。

    作品:

    router := gin.Default()
    router.Use(cors.Default())
    router.GET("/ping", pong)
    router.Run(":8082")
    

    不起作用:

    router := gin.Default()
    router.GET("/ping", pong)
    router.Use(cors.Default())
    router.Run(":8082")
    

    【讨论】:

    • 最重要的答案
    【解决方案2】:

    这对我有用 - 注意:直接设置标题。

    func CORSMiddleware() gin.HandlerFunc {
        return func(c *gin.Context) {
    
            c.Header("Access-Control-Allow-Origin", "*")
            c.Header("Access-Control-Allow-Headers", "*")
            /*
                c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
                c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
                c.Writer.Header().Set("Access-Control-Allow-Headers", "access-control-allow-origin, access-control-allow-headers")
                c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH")
            */
    
            if c.Request.Method == "OPTIONS" {
                c.AbortWithStatus(204)
                return
            }
    
            c.Next()
        }
    }
    

    【讨论】:

      【解决方案3】:
      func CORSMiddleware() gin.HandlerFunc {
          return func(c *gin.Context) {
      
              c.Header("Access-Control-Allow-Origin", "*")
              c.Header("Access-Control-Allow-Credentials", "true")
              c.Header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
              c.Header("Access-Control-Allow-Methods", "POST,HEAD,PATCH, OPTIONS, GET, PUT")
      
              if c.Request.Method == "OPTIONS" {
                  c.AbortWithStatus(204)
                  return
              }
      
              c.Next()
          }
      }
      

      那就用吧

      router = gin.New()  
      router.Use(CORSMiddleware())
      

      【讨论】:

        【解决方案4】:

        有包https://github.com/rs/cors,以正确的方式处理CORS请求。它具有流行路由器的示例,包括gin。那它:

        package main
        
        import (
            "net/http"
        
            "github.com/gin-gonic/gin"
            cors "github.com/rs/cors/wrapper/gin"
        )
        
        func main() {
            router := gin.Default()
        
            router.Use(cors.Default())
            router.GET("/", func(context *gin.Context) {
                context.JSON(http.StatusOK, gin.H{"hello": "world"})
            })
        
            router.Run(":8080")
        }
        

        通常情况下,您只需将router.Use(cors.Default()) 的默认处理添加到gin 中的中间件。够了。

        【讨论】:

          【解决方案5】:

          还有官方gin的处理CORS请求的中间件github.com/gin-contrib/cors

          您可以使用$ go get github.com/gin-contrib/cors 安装它,然后将这个中间件添加到您的应用程序中,如下所示: 主包

          import (
              "time"
          
              "github.com/gin-contrib/cors"
              "github.com/gin-gonic/gin"
          )
          
          func main() {
              router := gin.Default()
              // CORS for https://foo.com and https://github.com origins, allowing:
              // - PUT and PATCH methods
              // - Origin header
              // - Credentials share
              // - Preflight requests cached for 12 hours
              router.Use(cors.New(cors.Config{
                  AllowOrigins:     []string{"https://foo.com"},
                  AllowMethods:     []string{"PUT", "PATCH"},
                  AllowHeaders:     []string{"Origin"},
                  ExposeHeaders:    []string{"Content-Length"},
                  AllowCredentials: true,
                  AllowOriginFunc: func(origin string) bool {
                      return origin == "https://github.com"
                  },
                  MaxAge: 12 * time.Hour,
              }))
              router.Run()
          }
          

          【讨论】:

          • 如果您使用AllowOriginFunc,您在AllowOrigins 中定义的来源将被忽略。 AllowOriginFunc is a custom function to validate the origin. It take the origin as argument and returns true if allowed or false otherwise. If this option is set, the content of AllowOrigins is ignored.
          【解决方案6】:

          我们创建了一个最小的中间件。

          import (
              "github.com/gin-gonic/gin"
              "net/http"
          )
          
          type optionsMiddleware struct {
          
          }
          
          func CreateOptionsMiddleware() *optionsMiddleware{
              return &optionsMiddleware{}
          }
          
          func (middleware *optionsMiddleware)Response(context *gin.Context){
              if context.Request.Method == "OPTIONS" {
                  context.AbortWithStatus(http.StatusNoContent)
              }
          }
          

          并将其注册到 gin 中间件:

          app  := gin.New()
          app.Use(middleware.CreateOptionsMiddleware().Response).
              Use(next-middleware)......
          

          【讨论】:

            【解决方案7】:

            FWIW,这是我的 CORS 中间件,可以满足我的需求。

            func CORSMiddleware() gin.HandlerFunc {
                return func(c *gin.Context) {
                    c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
                    c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
                    c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
                    c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT")
            
                    if c.Request.Method == "OPTIONS" {
                        c.AbortWithStatus(204)
                        return
                    }
            
                    c.Next()
                }
            }
            

            【讨论】:

            • 为什么是 204?为什么不是 200?
            • HTTP NoContent coz duh!
            • 快 6 岁了,仍然很棒。很快就解决了我的问题。然而我想知道为什么这不是github官方文档的一部分......
            • 谢谢@Jack。只能在应用程序的根目录中添加它。不适用于我根据路由 url 添加了一些条件的应用程序的组路由。
            • c.Writer.Header().Set("Access-Control-Allow-Origin", "*")这可能会导致浏览器进入cors问题,在这种情况下需要指定特定的来源而不是*
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-03-10
            • 1970-01-01
            • 1970-01-01
            • 2021-12-02
            • 1970-01-01
            • 2020-11-23
            相关资源
            最近更新 更多