POST提交数据方式
0x00 背景
POST是在平日中很常见一种请求方式。相比于GET请求方式来说,POST更加的安全(不会被保存在浏览器历史或WEB服务器日志中)也支持更大的数据传输(GET请求因为是在URL添加参数所以受到URL长度的限制,即只支持2048个字符)。
通过POST提交的数据是需要放在请求头的消息体中,支持的格式主要有下面四种,而对于这四种的识别则是服务器端对请求头的content-tyep参数来进行判断的。
0x01 multipart/form-data
multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。 某表单的源代码如下:
<form action="upload.php" enctype="multipart/form-data" method="post"> <input name="myflie" type="file" /> <input type="submit" />
当在该表单输入内容进行提交的时候就会产生一个POST请求,其中的Content-Type参数值就会被设置为multipart/form-data
同时还会因为其特殊的格式增加一个boundary参数,这个参数是一个分隔符,分隔多个文件、表单项,他的值要足够的复杂或者随机,以保证不会与上传表单或者文件的内容出现重复。
请求头部分内容如下:
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开始,各个表单的内容使用--boundary分隔开,最后使用--boundary--来结束
0x02 application/x-www-form-urlencoded
这是最常见的POST提交数据的方法了吧。在源代码未知道enctype的时候默认就使用这种方式来提交。请求头类似于这样:
POST http://www.example.com HTTP/1.1 Content-Type: application/x-www-form-urlencoded;charset=utf-8 title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
可以看到消息体中提交的内容使用&进行连接,同时使用了URL编码,所以就像是把GET请求的参数放到消息体中一样。大部分服务端语言都对这种方式有很好的支持。很多时候,我们用 Ajax 提交数据时,也是使用这种方式。例如 JQuery 和 QWrap 的 Ajax,Content-Type 默认值都是「application/x-www-form-urlencoded;charset=utf-8」。
0x03 application/json
由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。同时json可以支持比普通的键值对更加复杂的数据,因此越来越多的人开始使用这种方式进行数据传输。
POST http://www.example.com HTTP/1.1 Content-Type: application/json;charset=utf-8 {"title":"test","sub":[1,2,3]}
0x04 补充
除了以上的3种情况之外,还有一些特殊的content-type。