目标文章链接:https://imququ.com/post/four-ways-to-post-data-in-http.html

以ASCII码来传输

HTTP协议是以ASCII码来传输,是把TCP/IP协议再包装了一层。

以ASCII码来传输,这就说明汉字啊或者一些符号啊需要转化才行。

HTTP请求分为三个部分,“状态行、请求头、消息主体”。

状态行很容易联想到状态码,100至500。1XX表示正在跑,2XX表示成功了,3XX表示重定向,4XX表示客户端有问题(常见的有这个地址无效),5XX表示服务器内部有问题。
请求头就是 Request Header,F12上的Headers的Request Headers。
消息主体 就是 body,需要传输的数据。

协议规定POST提交的数据必须放在消息主体(entity-body)中,但协议没有规定数据使用什么方式的编码。开发者,可以自己决定消息主体的格式,最要最后发送的HTTP请求满足上面的格式就可以。但是服务器发送后,要服务端解析成功才有意义。服务端通常是根据请求头(headers)中的Content-Type字段来获知请求中的消息主体是何种方式编码的,再对主体进行解析。所以说POST提交数据方案,包含了Content-Type和消息主体编码方式两部分。

这段话有两个启发,第一编码的格式可以自己规定。就是说我自己写服务端和客户端的话,我完全可以自己定义格式。不过难度很大。目前务实的是,我先把目前约定俗称的四种格式掌握好。

application/x-www-form-urlencoded

这是最常见的POST提交数据的方式了。浏览器原生的表单,如果不设置enctype属性,那么最终就会以application/x-www-form-urlencoded方式提交数据。

原来我把application/x-www-form-urlencoded和multipart/form-data这两种数据格式弄混了。在我自己写页面的时候,发现不定义enctype也可以提交,但是服务器端我是用python 的resp.form来解析的,那时候我就发现解析不出来。

请求类似如下方式

  1. POST http://www.example.com HTTP/1.1
  2. Content - Type: application/x-www-form-urlencoded;charset=utf-8
  3. sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3

首先,Content-Type被指定为 application/x-www-form-urlencoded; 其次,提交的数据按照key1=val1&key2=val2的方式进行编码,key和val都进行了URL转码。 再次,我们使用Ajax提交数据时,也是使用这种方式。

key1=val1&key2=val2这种编码方式看着很眼熟,get方式提交数据的时候不也是这个样子吗?由此,我觉得form-urlencoded作为post默认方式,不是偶然的,是和get一脉相承的。

multipart/form-data

这种方式用于上传表单。作者的话太简单,我来引述点其他资料。

http://blog.csdn.net/five3/article/details/7181521

http协议本身的原始方式不支持multipart/form-data,这个请求方式是在原始post方法上演变而来的。

  1. multipart/form-data 的基础方法是post,也就是说由post方法来组合实现的。
  2. multipart/form-data与post方法的不同之处:
    1 multipart/form-data的基础方法是post,也就是说由post方法来组合实现的。
    2 multipart/form-data与post方法不同之处在于:请求头,请求体。
    3 multipart/form-data的请求头必须包含一个特殊的头信息:Content-Type,且值也必须规定为multipart/form-data,同时还需要规定一个内容分割符用于分割请求体的多个post的内容,如文件内容和文本内容自然要分割开来。具体的头部信息如下:
    Content-Type:multipart/form-data;boundary=${bound}
    //${bound}是一个占位符,代表我们规定的分割符,分割符我们可以自己随意规定。如“——————————-1231242235346367”
    4 multipart/form-data的请求体也是一个字符串,不过和post的请求体不同的是它的构造方式,post是简单的key=value,而multipart/form-data则是添加了分割符等内容的构造体。格式如下:
    1. --${bound}
    2. Content-Disposition:form-data,name="filename"
    3. HTTP.pdf
    4. --${bound}
    5. Content-Disposition:form-data;name="file000";filename="HTTP协议详解.pdf"
    6. Content-Type:application/octet-stream
    7. .....

    这两种方式都是浏览器原生支持的,现阶段form表单也只支持这两种方式。

application/json

  1. POST http://www.example.com HTTP/1.1
  2. Content-Type: application/json;charset=utf-8
  3. {"title":"test","sub":[1,2,3]}

这种请求方式非常常见

text/xml

我觉得过时了,没必要关注了。

总结

post请求数据的时候有两种,传json的话就是application/json,不传json的话就是application/x-www-form-urlencoded
传文件的话用multipart/form-data.