我有一个基本的中间件,它是一个 Logger 函数,当我body, err := ioutil.ReadAll(r.Body)在接下来的每个函数中执行时,http.Request 将为空。但我希望身体包含信息。我能做些什么?开始:r.HandleFunc("/login", server.Loger(server.GetTokenHandler()).ServeHTTP).Methods("POST")所以它是中间件:func (server Server) Loger(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { body, _ := ioutil.ReadAll(r.Body) server.Log.Info(r.URL, " Methods: ", r.Method, string(body)) h.ServeHTTP(w, r) //Calls handler h })}现在 r.Body 将为空:func (server Server) GetTokenHandler() http.Handler{ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { body, err := ioutil.ReadAll(r.Body) if err != nil{ http.Error(w, "", 400) server.Log.Error(err) return } fmt.Print(string(body)) })}
1 回答
DIEA
TA贡献1820条经验 获得超2个赞
只能r.Body读取一次。没有其他办法了。
如果多个中间件需要访问数据,则需要将其保存为字节片并将其传递给后续中间件。
如果处理程序有上下文,您可以将正文数据作为上下文中的值传递。
另一种解决方案是 hack,是将数据存储在 ReponseWriter 的标头字段中。您不应忘记在返回时将其删除,以免将其发送出去。随后的中间件可以访问标头中的数据。
func (server Server) ReadBody(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, _ := ioutil.ReadAll(r.Body)
w.Header().Add("body", string(body))
h.ServeHTTP(w, r) //Calls handler h
w.Header().Del("body")
})
}
后续中间件将通过指令获取主体数据data := w.Header().Get("body")。请注意,标头值是字符串,而不是字节切片。
- 1 回答
- 0 关注
- 81 浏览
添加回答
举报
0/150
提交
取消