Golang中如何将HTTP请求的Body复制到新的HTTP请求

Golang中如何将HTTP请求的Body复制到新的HTTP请求 你好,

我收到一个HTTP请求,并希望将其正文复制到一个新的HTTP请求中,然后发送给第三方。

以下是我的代码,是否有更高效的方法?

此致

// create the outgoing http request body
httpRequestBody := &bytes.Buffer{}

// copy the incoming request body to the outgoing request body
_, err = io.Copy(httpRequestBody, ctx.Request.Body)
if err != nil {...}
defer ctx.Request.Body.Close()

// create the outgoing http request
httpRequest, err := http.NewRequestWithContext(context.Background(), http.MethodPut, thirdPartyAPIsURL, httpRequestBody)
if err != nil {...}

// send the out going http request
httpResponse, err := http.DefaultClient.Do(httpRequest)
if err != nil {...}
defer httpResponse.Body.Close()

更多关于Golang中如何将HTTP请求的Body复制到新的HTTP请求的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

谢谢。

更多关于Golang中如何将HTTP请求的Body复制到新的HTTP请求的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


抱歉解释得不够详细。我收到一个来自客户端的 HTTP 请求,利用其请求体,我创建了一个新的 HTTP 请求并将其发送给第三方 API。我正在将传入请求的请求体重定向到第三方。

我已更新代码并添加了更多解释。

ermanimer:

我收到来自客户端的HTTP请求

当我从客户端收到请求(GET、POST等)时,我以大致相同的方式读取请求体。

// Read the JSON data from the request body
body, err := io.ReadAll(r.Body)
if err != nil {
	http.Error(w, "Error reading request body", http.StatusBadRequest)
	return
}

ermanimer: 还有其他方法吗

如果你收到一个 HTTP 请求,它可能是一个 HTTP 响应吗?如果是这种情况,我会这样做(取决于所需的格式):

// read body into to map
var result map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&result)
if err != nil {
	fmt.Println(err.Error())
	return
}
fmt.Println(result)

在Golang中,将HTTP请求的Body复制到新的HTTP请求中,你的代码已经基本正确,但可以优化以避免重复读取和内存分配。以下是改进后的示例:

// 一次性读取原始请求体
bodyBytes, err := io.ReadAll(ctx.Request.Body)
if err != nil {
    // 处理错误
}
defer ctx.Request.Body.Close()

// 创建新请求,使用相同的body数据
httpRequest, err := http.NewRequestWithContext(
    context.Background(),
    http.MethodPut,
    thirdPartyAPIsURL,
    bytes.NewReader(bodyBytes),
)
if err != nil {
    // 处理错误
}

// 如果需要保留原始Content-Type等头部
httpRequest.Header = ctx.Request.Header.Clone()

// 发送请求
httpResponse, err := http.DefaultClient.Do(httpRequest)
if err != nil {
    // 处理错误
}
defer httpResponse.Body.Close()

如果担心大文件内存占用,可以使用io.TeeReader进行流式处理:

// 创建缓冲区存储body内容
var buf bytes.Buffer
teeReader := io.TeeReader(ctx.Request.Body, &buf)

// 先读取原始请求(如果需要处理原始请求)
originalBody, err := io.ReadAll(teeReader)
if err != nil {
    // 处理错误
}
defer ctx.Request.Body.Close()

// 使用缓冲区中的数据创建新请求
httpRequest, err := http.NewRequestWithContext(
    context.Background(),
    http.MethodPut,
    thirdPartyAPIsURL,
    bytes.NewReader(buf.Bytes()),
)
if err != nil {
    // 处理错误
}

对于需要同时处理原始请求体和转发请求体的场景,可以使用io.MultiReader

// 读取原始body
bodyBytes, err := io.ReadAll(ctx.Request.Body)
if err != nil {
    // 处理错误
}
defer ctx.Request.Body.Close()

// 处理原始body数据
// ...

// 创建转发请求
httpRequest, err := http.NewRequestWithContext(
    context.Background(),
    http.MethodPut,
    thirdPartyAPIsURL,
    bytes.NewReader(bodyBytes),
)
if err != nil {
    // 处理错误
}

这些方法避免了多次读取请求体,确保数据一致性并提高效率。

回到顶部