我在服务器端使用Golang编写http拦截器。我可以从r.Body
读取http请求正文。现在,如果我想修改正文内容,我该如何在控制权转交给下一个拦截器之前修改请求正文?
func(w http.ResponseWriter, r *http.Request) {
// Now I want to modify the request body, and
// handle(w, r)
}
我在服务器端使用Golang编写http拦截器。我可以从r.Body
读取http请求正文。现在,如果我想修改正文内容,我该如何在控制权转交给下一个拦截器之前修改请求正文?
func(w http.ResponseWriter, r *http.Request) {
// Now I want to modify the request body, and
// handle(w, r)
}
Body io.ReadCloser
似乎唯一的方法是用适合io.ReadCloser
接口的对象替换Body
。为此,您需要使用返回io.Reader
对象的任何函数构造Body
对象,并使用ioutil.NopCloser
将io.Reader
对象转换为io.ReadCloser
。
bytes.NewBufferString
NewBufferString创建并初始化一个新的Buffer,使用字符串s作为其初始内容。它旨在准备缓冲区以读取现有字符串。
strings.NewReader
(在下面的示例中使用)
NewReader返回从s读取的新Reader。它类似于bytes.NewBufferString但更高效且只读。
ioutil.NopCloser
NopCloser返回具有包装所提供的Reader r的无操作Close方法的ReadCloser。
new_body_content := "New content."
r.Body = ioutil.NopCloser(strings.NewReader(new_body_content))
但需要明确的是,为了不混淆应用程序的其他部分,您需要更改与Body
内容相关的Request
属性。大多数情况下只需更改ContentLength
属性即可:
r.ContentLength = int64(len(new_body_content))
在极少数情况下,如果您的新内容使用与原始Body
不同的编码方式,则可能会出现TransferEncoding
。
b = ioutil.ReadAll(r.Body); b[42] = 99; r.Body = ioutil.NopCloser(bytes.NewBuffer(b))
。非常简单。 - Volkerioutil.NopCloser
是我正在寻找的东西。你能否把它作为答案,这样我就可以给你积分了吗? - user1663023newBody := "新正文"; r.Body = ioutil.NopCloser(strings.NewReader(newBody)); r.ContentLength = int64(len(newBody))
- Izak Marais