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
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)
})
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.