【问题标题】:How to reuse request body of *http.Request between HTTP middleware handlers?如何在 HTTP 中间件处理程序之间重用 *http.Request 的请求体?
【发布时间】:2018-05-17 10:37:38
【问题描述】:

我使用 go-chi 作为 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
}

user.Create返回错误"unexpected end of JSON input"

其实,在我执行ioutil.ReadAll
user.Create之后就不再解析JSON了,
r.Body 中有一个空数组[]我该如何解决这个问题?

【问题讨论】:

标签: http go middleware


【解决方案1】:

外部处理程序将请求正文读取到 EOF。当调用内部处理程序时,不再从主体中读取任何内容。

要解决此问题,请使用先前在外部处理程序中读取的数据恢复请求正文:

func Registration(w http.ResponseWriter, r *http.Request) {
    b, err := ioutil.ReadAll(r.Body) 
    // ...other code
    r.Body = ioutil.NopCloser(bytes.NewReader(b))
    user.Create(w, r)
}

函数bytes.NewReader() 在字节片上返回io.Reader。函数ioutil.NopCloserio.Reader 转换为r.Body 所需的io.ReadCloser

【讨论】:

    【解决方案2】:

    最后,我能够通过这种方式恢复数据:

    r.Body = ioutil.NopCloser(bytes.NewBuffer(b))
    

    【讨论】:

    • 我认为有必要在此行之前调用 r.Body.Close()
    猜你喜欢
    • 1970-01-01
    • 2012-02-01
    • 2012-08-24
    • 2020-10-13
    • 2012-08-20
    • 2021-02-07
    • 2015-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多