脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|shell|

服务器之家 - 脚本之家 - Golang - Golang语言如何读取http.Request中body的内容

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

2024-03-28 11:08许野平 Golang

这篇文章主要介绍了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自动关闭的问题。

总结

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

原文链接:https://yeping.blog.csdn.net/article/details/80068161

延伸 · 阅读

精彩推荐
  • GolangGo语言中常见的文件操作分享

    Go语言中常见的文件操作分享

    文件操作应该是应用程序里非常常见的一种操作,无论是哪种应用场景,几乎都离不开文件的基本操作。Go语言中提供了三个不同的包去处理文件,下午就...

    孙琦Ray6762023-02-01
  • Golanggolang编程入门之http请求天气实例

    golang编程入门之http请求天气实例

    这篇文章主要介绍了golang编程入门之http请求天气实例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 ...

    embedsky5802020-05-17
  • GolangGo语言Handler详细说明

    Go语言Handler详细说明

    这篇文章主要介绍了Go语言Handler详细说明,Handler用于处理请求并给予响应。更严格地说,用来读取请求体、并将请求对应的响应字段(respones header)写入Respo...

    骏马金龙8972022-09-24
  • GolangGO语言中回调函数的使用

    GO语言中回调函数的使用

    本文主要介绍了GO语言中回调函数的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小...

    雨雨不怕雨7892023-03-06
  • Golang使用Go语言写一个Http Server的实现

    使用Go语言写一个Http Server的实现

    本文主要介绍了使用Go语言写一个Http Server的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    虎鲸不是鱼10982022-09-28
  • GolangGo语言中 Print Printf和Println 的区别解析

    Go语言中 Print Printf和Println 的区别解析

    这篇文章主要介绍了Go语言中 Print Printf和Println 的区别,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...

    岳来9402023-03-02
  • GolangGo语言method详解

    Go语言method详解

    这篇文章主要介绍了Go语言method详解,本文总结了在使用method的时候重要注意几点、指针作为receiver、method继承等内容,需要的朋友可以参考下 ...

    junjie2592020-04-09
  • Golang基于Golang实现延迟队列(DelayQueue)

    基于Golang实现延迟队列(DelayQueue)

    延迟队列是一种特殊的队列,元素入队时需要指定到期时间(或延迟时间),从队头出队的元素必须是已经到期的。本文将用Golang实现延迟队列,感兴趣的...

    jiaxwu6042022-11-23