我需要在中间件中获取请求主体。像这样:
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请求与正文。
为什么以及如何解决?
答案 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
}
}
这显然会将请求主体的所有副作用都存入内存,如果主体很大,该怎么办等等。而您的中间件正在从处理程序等处夺走一些控制权。