在 Go 中间件处理程序中重用 HTTP 请求体
在 Go 的 net/http 包中,中间件处理程序提供了一种便捷的方法来处理和修改传入的内容在由实际应用程序代码处理之前的 HTTP 请求。然而,当中间件处理程序需要重用前面的处理程序已读取的请求正文时,就会出现一个常见的挑战。
考虑以下代码片段:
func Registration(w http.ResponseWriter, r *http.Request) { b, err := ioutil.ReadAll(r.Body) // if you delete this line, the user will be created // ...other code // if all good then create new user user.Create(w, r) } ... func Create(w http.ResponseWriter, r *http.Request) { b, err := ioutil.ReadAll(r.Body) // ...other code // ... there I get the problem with parse JSON from &b }
在此场景中,注册处理程序将请求正文读取到变量 b 中,并将请求 r 传递给 user.Create 处理程序,该处理程序尝试再次读取正文。但是,这会导致错误,因为主体已被注册处理程序使用。
此问题的解决方案很简单:在读取请求主体后,在外部处理程序中恢复请求主体。这可以使用 bytes.NewReader() 和 io.NopCloser 函数来实现:
func Registration(w http.ResponseWriter, r *http.Request) { b, err := io.ReadAll(r.Body) // ...other code r.Body = io.NopCloser(bytes.NewReader(b)) user.Create(w, r) }
bytes.NewReader() 函数从字节切片创建 io.Reader,io.NopCloser 转换 io .Reader 为 r.Body 所需的 io.ReadCloser 类型。通过恢复主体,后续处理程序可以访问原始请求数据。
以上是如何在 Go 中间件处理程序中重用 HTTP 请求正文?的详细内容。更多信息请关注PHP中文网其他相关文章!