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。