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

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

服务器之家 - 脚本之家 - Golang - Go HTTP GET 请求可以发送 body 吗

Go HTTP GET 请求可以发送 body 吗

2023-11-27 17:28脑子进煎鱼了 Golang

前段时间遇到一个朋友,他跟我说他们在开发一个 Go 项目时,遇到了一个争议点,说来也好理解。WEB UI 端选择 GET、POST 类型时,程序是否要区分所传递的值(例如:Body),还是不管是什么类型都传。

大家好,我是煎鱼。

前段时间遇到一个朋友,他跟我说他们在开发一个 Go 项目时,遇到了一个争议点,说来也好理解。WEB UI 端选择 GET、POST 类型时,程序是否要区分所传递的值(例如:Body),还是不管是什么类型都传。

Go HTTP GET 请求可以发送 body 吗图片

一派认为无所谓,反正都能传。又没限制。

一派认为规范如此,不应该传。应该针对 HTTP POST 类型,使用 POST 请求的 body 来传递参数。在 GET 请求里使用 URI 来进行参数传递。

看着似乎都有各自的道理,僵持不下。

RFC7231 怎么说

要看互联网协议的相关标准,必然是 RFC 了。首先看看 RFC7231[1] 中的 4.3.1 小节是怎么说的。

如下摘抄:

A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.

大概意思:在 GET 类型的请求里使用 body 是一个没有定义的语义。如果在 GET 请求的 body 里传递参数可能会被某些实现方拒绝该请求。

也就是这个混着传的行为并不符合 RFC 规范,至少官方是不推荐不鼓励这样的使用方式。但并没有禁止这个行为。

记住这个结论。接下来我们进行测试。

程序支持程度

我们起一个 HTTP Sever 用于测试和验证,看看在具体的编程语言的实现中是否可以支持。

如下 Go 代码:

func hello(w http.ResponseWriter, req *http.Request) {
 b, _ := io.ReadAll(req.Body)
 w.Write(b)
}

func main() {
 http.HandleFunc("/hello_world", hello)
 http.ListenAndServe(":7001", nil)
}

在命令行执行 CURL 进行测试:

$ curl -X GET localhost:7001/hello_world -d '煎鱼'
煎鱼

看来在 Go 里面是可以的。

那既然 RFC 没有禁止,Go 的测试也正常。看来就是只是口头上的 “不鼓励” 和 “不推荐” 吗?

那别的场景也都支持吗?

实际上也不是,例如:XMLHttpRequest 规范[2] 中有明确提到:

Go HTTP GET 请求可以发送 body 吗图片

如果请求方法为 GET 或 HEAD,body 参数会被忽略。

总结

在 GET 类型里传 body 参数,从 RFC7231 标准来定义。官方是不推荐、不鼓励这么去使用的。

但是呢,这是一个没有明确禁止的事。

而从各个 HTTP 实现的客户端来看,一开始还是有不少不支持的。但掰扯了好多年后,大多数都支持了。(毕竟用户的诉求也是很重要的)

甚至印象最深的,ES 直接就在 GET 请求里传了 body:

Go HTTP GET 请求可以发送 body 吗图片

对应的 CURL:

curl -X GET "localhost:9200/my-index-000001/_search?from=40&size=20&pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "term": {
      "user.id": "kimchy"
    }
  }
}
'

但也有不支持的,例如在 Chrome 浏览器下测试 XMLHttpRequest、Fetch 对此都会忽略或出现报错。

Go HTTP GET 请求可以发送 body 吗图片

Fetch GET body

结论上来讲,GET 请求能不能传 body,这是一个 RFC 规范不鼓励。但是实现方大部分都支持的一个情况。

企业和团队内部的话,建议达成研发规范的共识即可。不过我个人而言,都会区分开。

参考资料

[1]RFC7231: https://datatracker.ietf.org/doc/pdf/rfc7231.pdf

[2]XMLHttpRequest 规范: https://xhr.spec.whatwg.org

原文地址:https://mp.weixin.qq.com/s/6ZMjo02qUA6jSWMP549ohw

延伸 · 阅读

精彩推荐
  • GolangGo语言获取本机逻辑CPU数量的方法

    Go语言获取本机逻辑CPU数量的方法

    这篇文章主要介绍了Go语言获取本机逻辑CPU数量的方法,实例分析了runtime库的操作技巧,需要的朋友可以参考下 ...

    两把刷子2452020-04-20
  • Golanggolang import自定义包方式

    golang import自定义包方式

    这篇文章主要介绍了golang import自定义包方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    loongshawn10002021-06-08
  • GolangGo 内存分配管理

    Go 内存分配管理

    这篇文章主要介绍了Go 内存分配管理,go 语言实际内存、虚拟内存怎么分配,延迟归还是什么机制?本文结合监控对内存管理进行了观测,深入学习golang对...

    编程技术4602022-09-05
  • Golang【Go微服务】一文带你玩转ProtoBuf

    【Go微服务】一文带你玩转ProtoBuf

    通过这篇文章,我们不仅学会了ProtoBuf的入门操作,还使用Go语言基于ProtoBuf编码解码了数据,进行了实战。进阶部分带大家了解了ProtoBuf如何定义消息、P...

    程序员升级打怪之旅7362022-11-09
  • Golang解决go build不去vendor下查找包的问题

    解决go build不去vendor下查找包的问题

    这篇文章主要介绍了解决go build不去vendor下查找包的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    zgcbj14442021-03-08
  • Golang简单聊聊Golang中defer预计算参数

    简单聊聊Golang中defer预计算参数

    在golang当中defer代码块会在函数调用链表中增加一个函数调用,下面这篇文章主要给大家介绍了关于Golang中defer预计算参数的相关资料,文中通过实例代码介绍...

    蓝色记忆5762022-09-12
  • Golang如何用Go判断元素是否在切片中

    如何用Go判断元素是否在切片中

    切片(Slice)是一个拥有相同类型元素的可变长度的序列,下面这篇文章主要给大家介绍了关于如何用Go判断元素是否在切片中的相关资料,文中通过实例代码介...

    恋喵大鲤鱼8242022-10-26
  • GolangGo语言包和包管理详解

    Go语言包和包管理详解

    这篇文章主要为大家介绍了Go语言包和包管理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪...

    ourlang7312022-09-02