《四种常见的 POST 提交数据方式》阅读笔记
目标文章链接: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提交数据的方式了。浏览器原生的<form>表单,如果不设置enctype属性,那么最终就会以application/x-www-form-urlencoded方式提交数据。
原来我把application/x-www-form-urlencoded和multipart/form-data这两种数据格式弄混了。在我自己写页面的时候,发现不定义enctype也可以提交,但是服务器端我是用python 的resp.form来解析的,那时候我就发现解析不出来。
请求类似如下方式
POST http://www.example.com HTTP/1.1
Content - Type: application/x-www-form-urlencoded;charset=utf-8
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协议本身的原始方式不支持multipart/form-data,这个请求方式是在原始post方法上演变而来的。
- multipart/form-data 的基础方法是post,也就是说由post方法来组合实现的。
- 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则是添加了分割符等内容的构造体。格式如下:
--${bound}
Content-Disposition:form-data,name="filename"
HTTP.pdf
--${bound}
Content-Disposition:form-data;name="file000";filename="HTTP协议详解.pdf"
Content-Type:application/octet-stream
.....
这两种方式都是浏览器原生支持的,现阶段form表单也只支持这两种方式。
application/json
POST http://www.example.com HTTP/1.1
Content-Type: application/json;charset=utf-8
{"title":"test","sub":[1,2,3]}
这种请求方式非常常见
text/xml
我觉得过时了,没必要关注了。
总结
post请求数据的时候有两种,传json的话就是application/json,不传json的话就是application/x-www-form-urlencoded
传文件的话用multipart/form-data.