Skip to main content

04.内置库net/http的使用

1 复制request body

为什么是复制而不是读取呢?如下代码:

读取请求体

    buf, _ := ioutil.ReadAll(r.Body)
fmt.Println(buf)// [123 ...] 成功读取出二进制的字符
buf, _ = ioutil.ReadAll(r.Body)
fmt.Println(buf)// [] 再读取,则是空的

看出来了吗?请求体只能读取一次然后就从上下文清空出去,这将导致下游在处理请求体时,由于没有数据而出错,所以数据拿到,还得恢复原状才行。 大概是这样做的:

复制请求体数据

    buf, _ := ioutil.ReadAll(r.Body)
fmt.Println(buf) // 上游数据 [2 100...]
r.Body = ioutil.NopCloser(bytes.NewBuffer(buf)) // 数据还回上下文
nextBuff, _:= ioutil.ReadAll(r.Body)
fmt.Println(nextBuff) // 下游数据 [2 100...]

封装下大概是这样子:

    // 声明复制函数
copyReq := func(req *http.Request) ([]byte, error) {
buf, err := ioutil.ReadAll(req.Body)
if err != nil {
return []byte(""), err
}
req.Body = ioutil.NopCloser(bytes.NewBuffer(buf)) // 数据还回上下文
    return buf, err
}
cp1, _ := copyReq(r);
fmt.Println(cp1) // [1 191 ...]
cp2, _ := copyReq(r);
fmt.Println(cp2) // [1 191 ...]
cp3, _ := copyReq(r);
fmt.Println(cp3) // [1 191 ...]