之前学请求、响应的时候只是过了一边,大致知道有这些东西。但这次真正要用的时候却又忘了到底该如何写,错误的请求头、请求体的格式导致esp8266
一直发送不了数据到服务器上,又重新看了遍请求request的知识,才终于搞明白
请求
最初的写法:
由于在esp8266上已经选择、连接好了了httpbin.org的穿透,就以为Host可以不用加了,于是产生了 最初的写法:
1 | POST /post?= HTTP/1.1 |
▲根据玩单片机的小伙伴说必须多出一行\r\n
,所以这边是有一行空行的
结果: 400 BAD_REQUEST
搜索过后得知 : 如果使用http 1.1协议的话主机名HOST字段是必须的
第二次写法:
1 | POST /post?= HTTP/1.1 |
可以注意到的是Host是顶层域名,/post
只是其中的一个路由
结果: 成功,这样就算可以正常发送post请求了
于是下一步就是研究如何上传数据
第三次写法:
1 | POST /post?= HTTP/1.1 |
于是这次都没有返回值了.
想起了表单是有形式的,于是添加了
-
Content-Type: application/x-www-form-urlencoded
- 这个形式的参数应该写成
a=1&b=..&..
- 注.如果请求网页的表单中没设置
enctype
属性,那么最终就会默认以application/x-www-form-urlencoded
方式提交数据。
- 这个形式的参数应该写成
-
如果是
Content-Type: application/json
- 则改写成
{'a':1 , 'b'=.. , ...}
- 则改写成
-
multipart/form-data
,我们使用表单上传文件时,必须让 form 的enctyped
等于这个值,请求示例-
1
2
3
4
5
6
7
8
9
10
11
12
13POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA-- -
说明: 首先生成了一个
boundary
用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以mutipart/form-data
来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 --boundary 开始,紧接着内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 --boundary-- 标示结束。关于mutipart/form-data
的详细定义,请前往 rfc1867 查看。
-
-
text/xml
,XML-RPC 是一种使用 HTTP 作为传输协议,XML 作为编码方式的远程调用规范。典型的 XML-RPC 请求是这样的:-
1
2
3
4
5
6
7
8
9
10
11
12POST http://www.example.com HTTP/1.1
Content-Type: text/xml
<!--?xml version="1.0"?-->
<methodcall>
<methodname>examples.getStateName</methodname>
<params>
<param>
<value><i4>41</i4></value>
</params>
</methodcall>
-
但是虽然能接受到返回的结果,但是响应数据中发现form
一直是空的,那就是参数没传过去,于是想到是不是格式的错误
第四次写法
后来上网找寻了一下结果发现我遗漏了模板中的\r\n\r\n
这行,即请求头 和 请求体 之间至少有一行换行!!!
1 | POST /get HTTP/1.1 |
中间的空行不能省略 , 这样httpbin.org那边才不返回 ERROR
或是BAD_REQUEST
但是数据还是发送不出
于是咨询了qk大佬以后,才发现原来请求头也必须要加上Content-Length:8
…
最终完成版
1 | POST /get HTTP/1.1 |
哎…本来很简单的事,竟然弄了一个多小时才搞定,真只能怪自己学艺不精了。幸好的是,还是调出来了。
附录:
HTTP请求报文解剖 :
组成
HTTP请求报文由3部分组成(请求行+请求头+请求体):
内容
格式
HttpWatch
HttpWatch是强大的网页数据分析工具,安装后将集成到Internet Explorer工具栏中。它不用代理服务器或一些复杂的网络监控工具,就能抓取请求及响应的完整信息,包括Cookies、消息头、查询参数、响应报文等,是Web应用开发人员的必备工具。
Author: Mrli
Link: https://nymrli.top/2019/03/01/构造一个能发数据的POST请求头/
Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.