Golang无法从request.GetBody()获取请求体。

25

我尝试通过request.GetBody()读取请求正文,因为我需要多次读取同一个请求正文,但我总是收到下面的错误。我检查了req.body是否为空,但它不是空的。我甚至不能调用req.GetBody()。我的Go版本是1.8.1。

 func read(res http.ResponseWriter, req *http.Request) {

     _, err := req.GetBody()
    if err != nil {
        res.Write([]byte(err.Error()))
        return
    }

}

错误:

http: panic serving [::1]:53174: runtime error: invalid memory address or nil pointer dereference
2个回答

48
GetBody()函数只适用于客户端请求(请参阅GetBody成员的文档:https://golang.org/pkg/net/http/#Request),但看起来你正在进行服务器端处理程序。因此,你需要使用req.Body成员,它是一个io.ReadCloser。要从io.ReadCloser读取数据,可以使用io/ioutil包和ReadAll()函数:
b, err := ioutil.ReadAll(req.Body)
if err != nil {
    panic(err)
}

fmt.Printf("%s", b)

ReadAll()函数的更多信息:https://golang.org/pkg/io/ioutil/#example_ReadAll


啊,好的,谢谢。这意味着,如果我想在通过一系列中间件处理程序传递请求时多次读取正文,我必须编写自己的服务器端GetBody(),还是有更好的解决方案? - jona jürgen
1
是的,您可以自己实现,或使用上下文(https://golang.org/pkg/net/http/#Request.Context 和 https://golang.org/pkg/net/http/#Request.WithContext)将信息沿着链传递。如果您使用上下文,我建议考虑使用 WithValue 选项,将 []byte 追加到一个众所周知的键中。 - PaulJ
1
谢谢PaulJ!我会看看两个选项 :) - jona jürgen

-12

这意味着你的req变量是nil


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接