如何在中间件中获取请求主体

时间:2018-07-13 14:39:58

标签: go

我需要在中间件中获取请求主体。像这样:

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请求与正文。 为什么以及如何解决?

1 个答案:

答案 0 :(得分:2)

您只能阅读一次请求正文,但是您只能阅读一次并创建您阅读内容的副本。使用三通阅读器

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
    }
}

这显然会将请求主体的所有副作用都存入内存,如果主体很大,该怎么办等等。而您的中间件正在从处理程序等处夺走一些控制权。