为了账号安全,请及时绑定邮箱和手机立即绑定

我如何在一个处理程序中更多地使用 http.Request?

我如何在一个处理程序中更多地使用 http.Request?

Go
慕神8447489 2023-08-07 15:05:50
我有一个基本的中间件,它是一个 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")。请注意,标头值是字符串,而不是字节切片。


查看完整回答
反对 回复 2023-08-07
  • 1 回答
  • 0 关注
  • 81 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信