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

Go 如何在中间件中获取请求主体,go,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() return func (w http.ResponseW

我需要在中间件中获取请求主体。比如:

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()
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
    }
}
但是我得到了带有body的POST请求的
s==”

为什么以及如何修复它?

您只能读取一次请求正文,但可以读取一次并创建所读取内容的副本。使用tee读取器或

或者这个答案:

两者都包括将身体读入记忆一次,然后复制一份。因此,当您在中间件中使用它时,您可以在将副本转发给处理程序之前将其重新分配给请求对象

对你来说,比如:

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

这显然具有请求主体进入内存的所有副作用,如果主体非常大等等,并且中间件正在从处理程序等处夺走一些控制权。您只能读取请求主体一次,但可以读取一次并创建所读取内容的副本。使用tee读取器或

或者这个答案:

两者都包括将身体读入记忆一次,然后复制一份。因此,当您在中间件中使用它时,您可以在将副本转发给处理程序之前将其重新分配给请求对象

对你来说,比如:

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

这显然会对内存中的请求体产生所有的副作用,如果请求体非常大等等,那么中间件会从处理程序中拿走一些控制权等等。

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