Different CORS settings for different paths?

I have created an application with Go in Gin-Gonic. In my frontend (Nuxt3/TypeScript) I always get a CORS error:

Access to fetch at ‘http://localhost:8081/api/v1/notion/database’ from origin ‘http://localhost:3000’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

I commented out all the endpoints of my application and built only these two endpoints step by step. With the same CORS config, the endpoints suddenly worked. I built the endpoints more and more and found the following error:

The /api/v1/notion endpoint works and I can access it. The /api/v1/notion/database endpoint does not work and returns the above CORS error. I use the official CORS middleware from Gin-Gonic.

func main(){
  r := gin.Default()
  r.Use(cors.New(cors.Config{
    AllowOrigins:     []string{"http://localhost:3000"},
    AllowMethods:     []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
    AllowHeaders:     []string{"Authorization", "Origin", "Content-Type", "Accept"},
    ExposeHeaders:    []string{"Content-Length"},
    AllowCredentials: true,
  }))
  r.GET("/api/v1/notion", func(c *gin.Context) {
    c.JSON(http.StatusOK, "👋 OK")
  })
  r.GET("/api/v1/notion/database", func(c *gin.Context) {
    c.JSON(http.StatusOK, "👋 OK")
  })
  r.Run(":8081")
}

The reqeust I send from the frontend looks like this for both:

async function sendOwnRequest(){
  const url1 = 'http://localhost:8081/api/v1/notion'
  const url2 = 'http://localhost:8081/api/v1/notion/database'
  const bearer="Bearer ey..."

  const response = await window.fetch(url1, {
    method: 'GET',
    headers: {'Authorization': bearer},
    mode: 'cors',
    credentials: 'include',
  })

  const response = await window.fetch(url2, {
    method: 'GET',
    headers: {'Authorization': bearer},
    mode: 'cors',
    credentials: 'include',
  })
}

Do you have any ideas what the problem could be, because both should be 100% identical except for the URL path. Is there a CORS property which I have to set?


Versions:

  • go version: go1.20 darwin/arm64
  • go list -m github.com/gin-gonic/gin: v1.9.1
  • go list -m github.com/gin-contrib/cors: v1.4.0
  • node –version: v18.17.0
  • npm –version: 9.6.7

  • As an update, I have recreated the two endpoints on a complete new Go instance, where the endpoints work. However, when I comment out all the code from my project and do a go mod tidy in my main project, the CORS error still comes up.

    – 

On the go server side code r.Run("8081") should be r.Run(":8081") // Note the colon before the port number

Apart from this i dont see any issue with the code, client code also looks good

Edit:
Ah, I think you might have missed the OPTIONS preflight check by browsers? just before making call to r.GET ?

r.OPTIONS("/api/v1/notion", func(c *gin.Context) {
    c.Status(http.StatusOK)
})

Leave a Comment