在机场赶制,可能比较匆忙,需要以后再改一下

post请求编码方式介绍

HTTP 请求以ascii码进行传输,一个http请求至少包含以下部分:

1
状态、请求头、消息主体

状态看起来应该是这样的:

1
POST http://127.0.0.1:5000/ HTTP/1.1

请求头是这样的:

1
2
3
4
5
6
7
8
9
10
11
Origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
Content-Length: 30
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Connection: keep-alive
Postman-Token: 186f6c8b-00c2-4020-e0c2-e6a7715fd9cb
Host: 127.0.0.1:5000
Cache-Control: no-cache
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate, br

消息主体里面的内容可以分成三种情况:

  • x-www-form-urlencoded
  • form-data
  • raw

(按照postman的形式分类)

一个http请求的结构如下:

1
2
3
<状态>
<请求头>
<消息主体>

比如像这样:[^1]

1
2
3
4
5
POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

user=ciaran&pwd=SunFlower

你可以在telnet中直接使用这种格式来发送http请求

telnet发送http请求的例子(Linux)

1
2
3
4
5
6
$ telnet
> open www.baidu.com 80
Trying 163.177.151.110...
Connected to www.a.shifen.com.
Escape character is '^]'.
GET / HTTP/1.1

最后一行是自己输入的。

如果发post请求,那就是用之前的代码取代最后一行的GET / HTTP/1.1

更好的方式获得更多的http参数是在浏览器中打开控制台network中对请求头进行复制。

screenshot

application/x-www-form-urlencoded

我们可以直接使用html的网页来发送这种类型的消息主体:

1
2
3
4
5
6
<form method='post' action='http://127.0.0.1:5000/' enctype="">
<input type="text" name='post_key1' value="post_value1"/><br>
<input type="text" name='post_key2' value="post_value2"/><br>
<input type="text" name='键3' value="值2"/><br>
<input type="submit" />
</form>

这个网页提交的http请求消息主体将是看起来像这样:

1
post_key1=post_value1&post_key2=post_value2&%E9%94%AE3=%E5%80%BC2

值得一提的是这样没有办法发出文件。如果请求中有文件数据,会当成字符串,直接只处理文件名。如果需要发出文件的话,就需要下面的这种方法。

multipart/form-data

要发出这种形式的post请求,我们必须让

表单的 enctype 等于 multipart/form-data

1
2
3
4
5
6
7
<form method='post' action='http://127.0.0.1:5000/' enctype="multipart/form-data">
<input type="text" name='post_key1' value="post_value1"/><br>
<input type="file" name="post_file"/><br>
<input type="text" name='post_key2' value="post_value2"/><br>
<input type="text" name='键3' value="值2"/><br>
<input type="submit" />
</form>

这种网页提交的请求的消息主体看起来是这样的:

1
2
3
4
5
6
7
------WebKitFormBoundaryPqzpWGwZxx2ANUPw
Content-Disposition: form-data; name="post_key1"

post_value1
------WebKitFormBoundaryPqzpWGwZxx2ANUPw
Content-Disposition: form-data; name="post_file"; filename="sample_file.txt"
Content-Type: text/plain
1
2
3
4
5
6
7
8
9
------WebKitFormBoundaryPqzpWGwZxx2ANUPw
Content-Disposition: form-data; name="post_key2"

post_value2
------WebKitFormBoundaryPqzpWGwZxx2ANUPw
Content-Disposition: form-data; name="键3"

值2
------WebKitFormBoundaryPqzpWGwZxx2ANUPw--

可以发现在请求头中有多了这么一句:

1
2
3
...
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryPqzpWGwZxx2ANUPw
...

这句话就是指定请求文件中各个部分以一个怎样的形式进行分割。这句话对应的就是消息主体中分割各个键值对的句子。

如果是传输文件的话,内容可以直接跟在描述的后面,然后就能在http中直接传输文件了。

raw(部分介绍)

raw数据结构对应的就是其他的数据类型,包括:

  • text/plain

    这个看起来与multipart/form-data的非常相似

    1
    2
    3
    4
    post_key1=post_value1
    post_file=sample_file.txt
    post_key2=post_value2
    键3=值2
  • application/json

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $.ajax({
    type:"POST",
    url:"127.0.0.1:5000",
    data: {Name:"sanmao",Password:"sanmaoword"},
    datatype: "html",//"xml", "html", "script", "json", "jsonp", "text".
    complete: function(XMLHttpRequest, textStatus){
    alert(XMLHttpRequest.responseText);
    alert(textStatus);
    },
    error: function(){
    }
    });

    消息主体如下:

    1
    {Name:"sanmao",Password:"sanmaoword"}
  • application/javascript

  • application/xml

  • text/xml

  • text/html

自己真的做的时候才是爆炸的时候,所以还是得留点东西让自己记下来。