Mrli
别装作很努力,
因为结局不会陪你演戏。
Contacts:
QQ博客园

构造一个能发数据的POST请求头

2019/09/15 爬虫 计算机网络知识
Word count: 1,124 | Reading time: 5min

之前学请求响应的时候只是过了一边,大致知道有这些东西。但这次真正要用的时候却又忘了到底该如何写,错误的请求头、请求体的格式导致esp8266一直发送不了数据到服务器上,又重新看了遍请求request的知识,才终于搞明白

请求

最初的写法:

由于在esp8266上已经选择、连接好了了httpbin.org的穿透,就以为Host可以不用加了,于是产生了 最初的写法

1
POST /post?= HTTP/1.1

▲根据玩单片机的小伙伴说必须多出一行\r\n,所以这边是有一行空行的

结果: 400 BAD_REQUEST

搜索过后得知 : 如果使用http 1.1协议的话主机名HOST字段是必须的

第二次写法:

1
2
POST /post?= HTTP/1.1 
Host:httpbin.org

可以注意到的是Host是顶层域名,/post只是其中的一个路由

结果: 成功,这样就算可以正常发送post请求了

于是下一步就是研究如何上传数据

第三次写法:

1
2
3
POST /post?= HTTP/1.1
Host: httpbin.org
tempt=57

于是这次都没有返回值了.

想起了表单是有形式的,于是添加了

  • 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
      13
      POST 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
      12
      POST 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
2
3
4
5
POST /get HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Connection:close

a=23&b=34

中间的空行不能省略 , 这样httpbin.org那边才不返回 ERROR或是BAD_REQUEST

但是数据还是发送不出

于是咨询了qk大佬以后,才发现原来请求头也必须要加上Content-Length:8

最终完成版

1
2
3
4
5
6
POST /get HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Connection:close
Content-Length:8

a=23&b=34

哎…本来很简单的事,竟然弄了一个多小时才搞定,真只能怪自己学艺不精了。幸好的是,还是调出来了。

附录:

HTTP请求报文解剖 :

组成

HTTP请求报文由3部分组成(请求行+请求头+请求体):

4

内容

5

格式

6

HttpWatch

HttpWatch是强大的网页数据分析工具,安装后将集成到Internet Explorer工具栏中。它不用代理服务器或一些复杂的网络监控工具,就能抓取请求及响应的完整信息,包括Cookies、消息头、查询参数、响应报文等,是Web应用开发人员的必备工具。

摘自HTTP请求行、请求头、请求体详解

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.

< PreviousPost
flask+nginx如何获得真实IP
NextPost >
为了不跑操而Excel——Orz
CATALOG
  1. 1. 请求
    1. 1.1. 最初的写法:
      1. 1.1.1. 结果: 400 BAD_REQUEST
    2. 1.2. 第二次写法:
      1. 1.2.1. 结果: 成功,这样就算可以正常发送post请求了
    3. 1.3. 第三次写法:
    4. 1.4. 第四次写法
    5. 1.5. 最终完成版
  2. 2. 附录:
    1. 2.1. HTTP请求报文解剖 :
      1. 2.1.1. 组成
      2. 2.1.2. 内容
      3. 2.1.3. 格式
    2. 2.2. HttpWatch