Golang语言如何读取http.Request中body的内容

 更新时间:2024年03月28日 10:14:37   作者:许野平  
这篇文章主要介绍了Golang语言如何读取http.Request中body的内容问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Golang读取http.Request中body内容

不罗嗦了,直接贴代码,不晓得为什么搞这么复杂,是不是因为担心 body 内容一次接受不全,所以搞了个接口来读取其中的内容?

import (
	...
	"io/ioutil"
	...
)

...

func myPost(w http.ResponseWriter, r *http.Request) {
	s, _ := ioutil.ReadAll(r.Body) //把	body 内容读入字符串 s
	fmt.Fprintf(w, "%s", s)        //在返回页面中显示内容。
}

...

Golang http.Request复用

针对除了Get以外的请求

package main

import (
    "net/http"
    "strings"
    )

func main(){
        reader := strings.NewReader("hello")
        req,_ := http.NewRequest("POST","http://www.abc.com",reader)
        client := http.Client{}
        client.Do(req) // 第一次会请求成功
        client.Do(req) // 请求失败
}

第二次请求会出错

http: ContentLength=5 with Body length 0

原因是第一次请求后req.Body已经读取到结束位置,所以第二次请求时无法再读取body,

解决方法:

重新定义一个ReadCloser的实现类替换req.Body

package reader

import (
    "io"
    "net/http"
    "strings"
    "sync/atomic"
)

type Repeat struct{
    reader io.ReaderAt
    offset int64
}

// Read 重写读方法,使每次读取request.Body时能从指定位置读取
func (p *Repeat) Read(val []byte) (n int, err error) {
    n, err = p.reader.ReadAt(val, p.offset)
    atomic.AddInt64(&p.offset, int64(n))
    return
}

// Reset 重置偏移量
func (p *Repeat) Reset(){
        atomic.StoreInt64(&p.offset,0)
}

func (p *Repeat) Close() error {
    // 因为req.Body实现了readcloser接口,所以要实现close方法
    // 但是repeat中的值有可能是只读的,所以这里只是尝试关闭一下。
    if p.reader != nil {
            if rc, ok := p.reader.(io.Closer); ok {
                return rc.Close()
            }
        }
    return nil
}

func doPost()  {
    client := http.Client{}
    reader := strings.NewReader("hello")
    req , _ := http.NewRequest("POST","http://www.abc.com",reader)
    req.Body = &Repeat{reader:reader,offset:0}
    client.Do(req)
    // 将偏移量重置为0
    req.Body.(*Repeat).Reset()
    client.Do(req)
}

这样就不会报错了,因为也重写了Close()方法,所以同时也解决了request重用时,req.Body自动关闭的问题。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Go 基于令牌桶的限流器实现

    Go 基于令牌桶的限流器实现

    如果一般流量过大,下游系统反应不过来,这个时候就需要限流了,本文主要介绍了Go 基于令牌桶的限流器实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • 一文带你了解GO语言中方法的应用

    一文带你了解GO语言中方法的应用

    GO 语言中的方法实际上和函数是类似的,只不过在函数的基础上多了一个参数,这篇文章主要为大家介绍一下GO语言中方法的应用,需要的可以参考下
    2023-09-09
  • 详解Go语言中的Slice链式操作

    详解Go语言中的Slice链式操作

    这篇文章主要为大家详细介绍了Go语言中的Slice链式操作的相关知识,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解一下
    2023-04-04
  • Go语言中数组的基本用法演示

    Go语言中数组的基本用法演示

    这篇文章主要介绍了Go语言中数组的基本用法演示,包括一个冒泡排序算法的简单实现,需要的朋友可以参考下
    2015-10-10
  • Golang使用ini库读取配置详情

    Golang使用ini库读取配置详情

    这篇文章主要介绍了Golang使用ini库读取配置详情,go-ini是一个非常方便、高效的go配置文件操作库。使用它在项目中读取和修改配置文件,下文相关资料需要的小伙伴可可以参考一下
    2022-04-04
  • 浅析Go语言编程当中映射和方法的基本使用

    浅析Go语言编程当中映射和方法的基本使用

    这篇文章主要介绍了浅析Go语言编程当中映射和方法的基本使用,是golang入门学习中的基础知识,需要的朋友可以参考下
    2015-10-10
  • 在Gin框架中正确删除Cookie的操作指南

    在Gin框架中正确删除Cookie的操作指南

    在现代Web开发中,Cookie管理是构建用户友好应用的关键环节,Gin作为Go语言中最受欢迎的Web框架之一,提供了简洁而强大的Cookie处理机制,本文将深入探讨如何在Gin框架中正确删除Cookie,需要的朋友可以参考下
    2025-08-08
  • 详解Golang中Channel的用法

    详解Golang中Channel的用法

    如果说goroutine是Go语言程序的并发体的话,那么channels则是它们之间的通信机制。这篇文章主要介绍Golang中Channel的用法,需要的朋友可以参考下
    2020-11-11
  • 简介Go语言中的select语句的用法

    简介Go语言中的select语句的用法

    这篇文章主要介绍了简介Go语言中的select语句的用法,是golang入门学习中的基础知识,需要的朋友可以参考下
    2015-10-10
  • Golang信号处理及如何实现进程的优雅退出详解

    Golang信号处理及如何实现进程的优雅退出详解

    这篇文章主要给大家介绍了关于Golang信号处理及如何实现进程的优雅退出的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-03-03

最新评论