我如何才能在一个处理程序中使用更多 http.Request?
How i can use http.Request more then in one handler?
我有一个基本的中间件,它是一个 Logger 函数,当我在接下来的每个函数中执行 body, err := ioutil.ReadAll(r.Body)
时,http.Request 将为空。但我希望 body 包含信息。我能做什么?
开始:
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))
})
}
r.Body
只能读取一次。没有其他办法了。
如果多个中间件需要访问数据,则需要将其保存一个字节片,传递给后续的中间件。
如果处理程序有上下文,您可以将 body 数据作为上下文中的值传递。
另一种解决方案是 hack,将数据存储在 ReponseWriter 的 header 字段中。退货时不要忘记取下,以免寄出。随后的中间件可能会访问 header.
中的数据
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")
获取body数据。请注意,header 值是一个字符串,而不是字节片。
我有一个基本的中间件,它是一个 Logger 函数,当我在接下来的每个函数中执行 body, err := ioutil.ReadAll(r.Body)
时,http.Request 将为空。但我希望 body 包含信息。我能做什么?
开始:
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))
})
}
r.Body
只能读取一次。没有其他办法了。
如果多个中间件需要访问数据,则需要将其保存一个字节片,传递给后续的中间件。
如果处理程序有上下文,您可以将 body 数据作为上下文中的值传递。
另一种解决方案是 hack,将数据存储在 ReponseWriter 的 header 字段中。退货时不要忘记取下,以免寄出。随后的中间件可能会访问 header.
中的数据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")
获取body数据。请注意,header 值是一个字符串,而不是字节片。