天天看点

HTTP - GET 通过 Body 来发送数据 - 学习/实践

1.应用场景

学习了解http的get请求方法的用法及不知道的信息.

2.学习/操作

1.博文阅读 //先阅读完

https://yanbin.blog/why-http-get-cannot-sent-data-with-reuqest-body/#more-8193   //谁说 HTTP GET 就不能通过 Body 来发送数据呢?

下面截图:

HTTP - GET 通过 Body 来发送数据 - 学习/实践

2.实践/验证过程

环境: Windows 10 64位  PHP/Laravel 7.x

方式一: curl

code:

HTTP - GET 通过 Body 来发送数据 - 学习/实践

使用git bash 进行curl 分别进进行GET/POST请求

curl -H 'Content-Type: application/json' -X GET -d '{"name":"XBox","price":3999}' http://laravel7.test/body

curl -H 'Content-Type: application/json' -X POST -d '{"name":"XBox","price":3999}' http://laravel7.test/body

cmd:

Note: cmd与git bash下请求, 格式要求有些区别, cmd下不能使用单引号, 以及参数要转义双引号.

curl -H "Content-Type: application/json" -X GET -d {\"name\":\"XBox\",\"price\":3999} http://laravel7.test/body

curl -H "Content-Type: application/json" -X POST -d {\"name\":\"XBox\",\"price\":3999} http://laravel7.test/body

或者

curl -H "Content-Type: application/json" -X GET -d "{\"name\":\"XBox\",\"price\":3999}" http://laravel7.test/body

curl -H "Content-Type: application/json" -X POST -d "{\"name\":\"XBox\",\"price\":3999}" http://laravel7.test/body

HTTP - GET 通过 Body 来发送数据 - 学习/实践
结果如下:
HTTP - GET 通过 Body 来发送数据 - 学习/实践

由上可知: 

GET方法在curl实现[而非协议]上, 只是支持request body传递参数的, 而且laravel 7.x 也只支持获取GET 请求体参数的.

方式二: postman

code:

HTTP - GET 通过 Body 来发送数据 - 学习/实践
使用form-data时, 并不能接收到请求体中参数.
HTTP - GET 通过 Body 来发送数据 - 学习/实践
如果使用content-Type: "application/json", 则可以正常接收参数
HTTP - GET 通过 Body 来发送数据 - 学习/实践

原因: PHP使用表单进行数据提交时, 支持GET/POST请求方法, 

GET: 服务端只获取uri中的参数.

POST: 服务端获取uri与请求体中的参数.

如改成POST请求,即可接收参数:

HTTP - GET 通过 Body 来发送数据 - 学习/实践

Note:

1.上面文章中有言, postman不支持GET方法携带body [当选择get方式时, body变为不可点击状态], 目前来看, 并不会变灰

而且, 可以使用content-type=application/json时的请求体进行传递参数.

HTTP - GET 通过 Body 来发送数据 - 学习/实践

该截图是使用postman 去请求kibana查询log [ElasticSearch]

2.如果使用PHP原生语言来处理, 要处理的东西稍微有点多~~,

暂时就直接使用框架来做测试验证.[如果PHP框架支持, 那么PHP原生也一定是支持的]

后续补充

...

3.问题/补充

1.关于get请求body传参,并不推荐通过body传参,可以参考stackoverflow关于该问题的回答  -- 1 year ago

https://stackoverflow.com/questions/978061/http-get-with-request-body

是的,实现上并不保证能传输,接收 get body 数据

2.get请求只是帮你把body串在query string中.

虽然说HTTP 1 是一个文本协议,但 Get Request 的 body 它也不是网址的一部份。查看请求协议数据,Get 的 Body 仍然是请求头空一行后的数据。

3.很多人讨论GET和POST的时候很容易就从“协议”讨论到“实现”上去了。  -- 2 years ago

协议里说的是,GET是从服务器取回数据,POST是发送数据,HTTP请求有header,有body。

但是实现怎么样,协议就不管了。

本文章的HTTPClient,curl,postman,浏览器,这些都是实现。

所以我觉得讨论GET和POST区别的前提是,弄明白协议和实现的区别。

比如别人可以说对于Chrome,get的区别是不能带body,这就没问题了。

然而协议里确实说了哪些方法带body是没有意义并可能会产生问题,所以你硬给get加一个body也是属于不遵循规范的,尽管可能成功但是后果自担。所以说get不能带body是正确的说法.

本文并没有建议去违反语义在 GET 请求中传递 body。由于 HTTP/1.1 是基于文本的协议,所以头后空一行后的数据都是 body,所以协议本身未作限制,但是有一个语义上的建议--不应在 GET 请求中放 body

这里有个比较好的回答: https://stackoverflow.com/questions/978061/http-get-with-request-body?answertab=active#tab-top

4.在浏览器里如何让get请求携带body呢?  -- 2 years ago

不行。从协议方面来说,GET 是可以带 body 的,但是不赞成这么做,所以好多工具并没有去提供支持。基本上也不要用 GET 来携带 body 数据。

对啊,我发现XHR内部就把body给移除了。

TBD

4.参考

https://yanbin.blog/why-http-get-cannot-sent-data-with-reuqest-body/#more-8193   //谁说 HTTP GET 就不能通过 Body 来发送数据呢?

https://www.ietf.org/standards/rfcs/  //RFC文档

后续补充

...

继续阅读