【问题标题】:How to get the request body in the middleware如何在中间件中获取请求体
【发布时间】:2018-12-21 23:36:48
【问题描述】:

我需要在中间件中获取请求正文。比如:

return func(w http.ResponseWriter, req *http.Request) {

    data, err := handler(w, req)

    if err != nil {
        buf := new(bytes.Buffer)
        buf.ReadFrom(req.Body)
        s := buf.String()

但我得到s == "" 带有正文的POST 请求。 为什么以及如何解决?

【问题讨论】:

  • 这里的处理程序是什么?您是在写信响应处理程序吗?请发布您传递请求和响应对象的处理程序函数的代码。
  • 请求体直接从客户端连接读取,只能读取一次。
  • @Adrian,谢谢。你能创建答案吗?
  • 非常酷的问题!为什么要投反对票?

标签: go


【解决方案1】:

您只能阅读请求正文一次,但您可以阅读一次并创建所阅读内容的副本。使用任何一个发球台阅读器

https://golang.org/pkg/io/#example_TeeReader

或者这个答案:

https://stackoverflow.com/a/23077519/6376471

两者都包括将正文读入内存一次,然后进行复制。这样,当您在中间件中使用它时,您可以将副本重新分配给请求对象,然后再将其转发给处理程序。

对你来说是这样的:

return func (w http.ResponseWriter, req *http.Request) {
    buf, err := ioutil.ReadAll(r.Body) // handle the error
    rdr1 := ioutil.NopCloser(bytes.NewBuffer(buf))

    req.Body = rdr1
    data, err := handler(w, req)
    if err != nil {
        s := buf.String()
        // ... trimmed
    }
}

这显然会将请求正文的所有副作用都放入内存中,如果正文非常大等会怎样。而您的中间件正在从处理程序等处夺走一些控制权。

【讨论】:

    猜你喜欢
    • 2019-06-03
    • 2021-08-02
    • 1970-01-01
    • 2015-07-24
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    相关资源
    最近更新 更多