Go Gin中间件将HEAD请求转为GET返回404问题咨询
问题原因
你在中间件中修改请求方法的时机太晚了。Gin收到请求后会先完成路由匹配,再执行注册的中间件链。你收到HEAD请求时,Gin先匹配HEAD对应的路由,没匹配到就已经确定返回404,此时你在中间件里修改请求方法为GET不会重新触发路由匹配,所以最终还是返回404。
可行解决建议
- 方案1:修改完请求方法后手动触发重新路由匹配
你可以在把请求方法改为GET后,调用c.HandleContext(c)让Gin用新的请求方法重新做路由匹配,然后终止当前的中间件链即可。另外要注意符合HEAD请求的规范:响应不能返回Body,所以需要额外记录原始请求类型,最后清空响应Body。
修改后的中间件代码示例:
func CORS() 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", "*") c.Writer.Header().Set("Access-Control-Allow-Methods", "*") if c.Request.Method == "OPTIONS" { c.AbortWithStatus(http.StatusNoContent) return } // 记录原始请求是否为HEAD isHead := c.Request.Method == "HEAD" if isHead { c.Request.Method = "GET" // 重新触发路由匹配 c.HandleContext(c) // 终止原链路执行 c.Abort() // HEAD请求清空响应Body,仅保留Header c.Writer.WriteHeaderNow() return } c.Next() } }
- 方案2:路由层同时绑定GET和HEAD方法
如果可以调整路由代码,直接给每个GET路由同时绑定HEAD方法即可,不需要修改请求方法,性能更好也更稳定,示例:
// 同一个handler同时绑定GET和HEAD请求 r.GET("/api/xxx", xxxHandler) r.HEAD("/api/xxx", xxxHandler)
内容的提问来源于stack exchange,提问作者brian goo
相关产品推荐
相关产品推荐

