2

Problem Description

I have tried several solutions, but none of them worked. Here are the details:

I have a website configured at localhost:8080, and I want this web app to access the Gin server at localhost:9999 using Axios.

Here are the solutions I have tried:

func main() {
    r.Use(cors.Default())
    //r.Use(Cors())
    //r.Use(Cors1())
    r.Use(Cors3())
    r.POST("/inlog", func(c *gin.Context) {
        print(c)
        c.JSON(200, gin.H{"status": "OK", "message": "pong",})
    })

    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    r.Run(":9999")
}

func Cors() gin.HandlerFunc {
    return cors.New(cors.Config{
        AllowAllOrigins:  true,
        AllowMethods:     []string{"POST", "GET", "PUT", "DELETE", "OPTIONS"},
        AllowHeaders:     []string{"*"},
        ExposeHeaders:    []string{"Content-Length", "Authorization", "Content-Type"},
        AllowCredentials: true,
        MaxAge:           12 * time.Hour,
    },
    )
}

func Cors1() gin.HandlerFunc {
    return func(c *gin.Context) {
        method := c.Request.Method
        origin := c.Request.Header.Get("Origin")
        if origin != "" {
            c.Header("Access-Control-Allow-Origin", origin)
            c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
            c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization")
            c.Header("Access-Control-Allow-Credentials", "true")
            c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar")
        }
        if method == "OPTIONS" {
            c.Header("Access-Control-Allow-Origin", origin)
            c.Header("Access-Control-Allow-Methods", "OPTIONS")
            c.Header("Access-Control-Allow-Headers", "*")
            c.AbortWithStatus(http.StatusNoContent)
        }
        c.Next()
    }
}

func Cors3() gin.HandlerFunc {
    return func(context *gin.Context) {
        method := context.Request.Method
        context.Header("Access-Control-Allow-Origin", "*")
        context.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token, x-token")
        context.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PATCH, PUT")
        context.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
        context.Header("Access-Control-Allow-Credentials", "true")

        if method == "OPTIONS" {
            context.AbortWithStatus(http.StatusNoContent)
        }
        context.Next()
    }
}

Unfortunately, these three solutions cannot solve my problem. They only allow my website to access the server using the GET method, while POST requests always result in an error:

Access to XMLHttpRequest at 'http://127.0.0.1:9999/inlog/' from origin 'http://127.0.0.1:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Any ideas?

jub0bs
  • 60,866
  • 25
  • 183
  • 186
Iteravse
  • 21
  • 2
  • Try using `return` instead of `c.AbortWithStatus`. – mkopriva May 02 '23 at 09:25
  • 1
    Haven't used gin, but with the default http.Mux `"/inlog/" != "/inlog"`. Try removing the trailing slash in the frontend, or add one in the server. – Peter May 02 '23 at 10:03
  • Try @Peter's suggestion first. This looks like the issue. If it still does not work, check the requests log in DevTools and share them. See https://stackoverflow.com/a/75935458/1369400 for how to diagnose such kind of problem. – Zeke Lu May 02 '23 at 10:15
  • What does the client code look like? Edit your question and add the code responsible for sending the problematic request. – jub0bs May 02 '23 at 12:20
  • `Cors` likely fails because Gin's CORS middleware is designed to ignore the wildcard exception for `Access-Control-Allow-Headers`. `Cors1` is incorrect (not enough room in a comment to explain why). `Cors3` is incompatible with credentialed requests. Don't try to re-implement CORS by manually setting headers, esp. if you're not intimately familiar with the protocol. Instead, rely on some well-designed library. I'm biased, but I recommend [jub0bs/fcors](https://pkg.go.dev/github.com/jub0bs/fcors); it's [compatible with Gin](https://github.com/jub0bs/fcors-examples/blob/main/gin/main.go). – jub0bs May 02 '23 at 12:25

1 Answers1

0

You did not show us your request and how it was made. But once I had problems with that too and the problem was the slash in the request.

Note that your route do not have the slash at end.

    r.POST("/inlog", func(c *gin.Context) {
       //Rest of your code
    }

If your client is calling it with a slash at end, it might turn in error for you together with a 301 error message.

So make sure you are calling http://127.0.0.1:9999/inlog and NOT http://127.0.0.1:9999/inlog/