英文:
Cors React and Gin-Gonic Gin
问题
我在开发环境中遇到了一个问题,实现了React前端和Go语言Gin-Gonic框架之间的跨域资源共享。下面是浏览器控制台的日志:
React应用程序发送POST请求的控制台日志:
这是Go框架接收到的请求,可以看到预检请求未经验证
我尝试了两种方法,一种是验证预检请求并在React的OPTIONS请求中返回200,如下所示:
func preflight(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Headers", "access-control-allow-origin, access-control-allow-headers")
c.JSON(http.StatusOK, struct{}{})
}
这种方法没有帮助,另外,我在访问控制允许的来源中包含了一个通配符域名的中间件,以及http://localhost:3000,如下所示:
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()
}
}
我还尝试了gin cors包,如此处所示:github.com/gin-contrib/cors,但请求仍然被阻止。
这些是我的路由的一部分:
r := gin.Default()
//r := gin.New()
config := cors.DefaultConfig()
config.AllowOrigins = []string{"*"}
// config.AllowOrigins = []string{"http://google.com", "http://facebook.com"}
// config.AllowAllOrigins = true
r.Use(cors.New(config))
//system routes
router.NotFound(r)
router.NoMethods(r)
//static routes
router.ServeStatic(r)
这是我的路由方法:
func NotFound(route *gin.Engine) {
route.NoRoute(func(c *gin.Context) {
c.JSON(404, gin.H{"msg": "Not Found"})
})
}
func NoMethods(route *gin.Engine) {
route.NoMethod(func(c *gin.Context) {
c.JSON(405, gin.H{"msg": "Not allowed"})
})
}
//Serve frontend static files
func ServeStatic(route *gin.Engine) {
route.Use(static.Serve("/", static.LocalFile("./views/public", true)))
route.Use(auth.CORSMiddleware())
api := route.Group("/api")
{
api.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
}
}
Go版本是go1.18.1 linux/amd64
"axios": "^0.24.0",
"react": "^18.1.0"
英文:
I have run into a problem implementing cross origin resource sharing in the development environment, between a react front end and Go-lang Gin-Gonic framework, below is the console log from the browser
Console log from the react application sending a post request
This is the received request from the Go framework, as can be seen, the preflight request is not validated
I have attempted two hacks, one is validating the preflight request and passing a 200 on the react OPTIONS as seen below
func preflight(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Headers", "access-control-allow-origin, access-control-allow-headers")
c.JSON(http.StatusOK, struct{}{})
}
This hack was not of help, additionally ,i included a middleware with a wildcard domain in the access control allow origin, as well as with http://localhost:3000 as shown below
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()
}
}
I also tried the gin cors package as shown here github.com/gin-contrib/cors but the request is still being blocked
These are part of my routes
r := gin.Default()
//r := gin.New()
config := cors.DefaultConfig()
config.AllowOrigins = []string{"*"}
// config.AllowOrigins = []string{"http://google.com", "http://facebook.com"}
// config.AllowAllOrigins = true
r.Use(cors.New(config))
//system routes
router.NotFound(r)
router.NoMethods(r)
//static routes
router.ServeStatic(r)
Methods
func NotFound(route *gin.Engine) {
route.NoRoute(func(c *gin.Context) {
c.JSON(404, gin.H{"msg": "Not Found"})
})
}
func NoMethods(route *gin.Engine) {
route.NoMethod(func(c *gin.Context) {
c.JSON(405, gin.H{"msg": "Not allowed"})
})
}
//Serve frontend static files
func ServeStatic(route *gin.Engine) {
route.Use(static.Serve("/", static.LocalFile("./views/public", true)))
route.Use(auth.CORSMiddleware())
api := route.Group("/api")
{
api.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
}
The go version is go version go1.18.1 linux/amd64
"axios": "^0.24.0",
"react": "^18.1.0",
答案1
得分: 1
尝试将CORS中间件移动到handleFunc之前。
示例:
func (h *Handler) InitRoutes() *gin.Engine {
router := gin.New()
router.Use(h.setHeaders)
router.GET("/", h.getRecordsByFilter)
router.GET("/:uuid", h.getRecordByUuid)
router.POST("/", h.createRecord)
router.PUT("/:uuid", h.updateRecord)
router.DELETE("/:uuid", h.deleteRecord)
return router
}
请注意,这是一个示例代码片段,你需要根据自己的实际情况进行相应的修改。
英文:
Try to move CORS middleware before your handleFunc
Example:
func (h *Handler) InitRoutes() *gin.Engine {
router := gin.New()
router.Use(h.setHeaders)
router.GET("/", h.getRecordsByFilter)
router.GET("/:uuid", h.getRecordByUuid)
router.POST("/", h.createRecord)
router.PUT("/:uuid", h.updateRecord)
router.DELETE("/:uuid", h.deleteRecord)
return router
}
答案2
得分: 0
问题出在来自React前端的凭据上。
handleSubmit(event) {
const {email,password} = this.state;
axios.post("http://localhost:3000/auth/register",
{email: email, password: password},{
withCredentials: true}).then(response => {
console.log("registration res", response);
console.log("response data",response.data);
}).catch(error => {
console.log("registration error", error);
});
event.preventDefault();
}
英文:
The problem was with credentials true from the react front-end
handleSubmit(event) {
const {email,password} = this.state;
axios.post("http://localhost:3000/auth/register",
{email: email, password: password},{
withCredentials: true}).then(response => {
console.log("registration res", response);
console.log("response data",response.data);
}).catch(error => {
console.log("registratino error", error);
});
event.preventDefault();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论