目標文章鏈接:https://imququ.com/post/four-ways-to-post-data-in-http.html
以ASCII碼來傳輸
HTTP協(xié)議是以ASCII碼來傳輸阅仔,是把TCP/IP協(xié)議再包裝了一層爬迟。
以ASCII碼來傳輸台腥,這就說明漢字啊或者一些符號啊需要轉化才行。
HTTP請求分為三個部分掀序,“狀態(tài)行、請求頭、消息主體”萄焦。
狀態(tài)行很容易聯(lián)想到狀態(tài)碼,100至500冤竹。1XX表示正在跑拂封,2XX表示成功了,3XX表示重定向鹦蠕,4XX表示客戶端有問題(常見的有這個地址無效)冒签,5XX表示服務器內部有問題。
請求頭就是 Request Header钟病,F(xiàn)12上的Headers的Request Headers萧恕。
消息主體 就是 body,需要傳輸?shù)臄?shù)據(jù)肠阱。
協(xié)議規(guī)定POST提交的數(shù)據(jù)必須放在消息主體(entity-body)中票唆,但協(xié)議沒有規(guī)定數(shù)據(jù)使用什么方式的編碼。開發(fā)者屹徘,可以自己決定消息主體的格式走趋,最要最后發(fā)送的HTTP請求滿足上面的格式就可以。但是服務器發(fā)送后噪伊,要服務端解析成功才有意義簿煌。服務端通常是根據(jù)請求頭(headers)中的Content-Type字段來獲知請求中的消息主體是何種方式編碼的,再對主體進行解析鉴吹。所以說POST提交數(shù)據(jù)方案姨伟,包含了Content-Type和消息主體編碼方式兩部分。
這段話有兩個啟發(fā)豆励,第一編碼的格式可以自己規(guī)定夺荒。就是說我自己寫服務端和客戶端的話,我完全可以自己定義格式肆糕。不過難度很大般堆。目前務實的是,我先把目前約定俗稱的四種格式掌握好诚啃。
application/x-www-form-urlencoded
這是最常見的POST提交數(shù)據(jù)的方式了淮摔。瀏覽器原生的<form>表單,如果不設置enctype屬性始赎,那么最終就會以application/x-www-form-urlencoded方式提交數(shù)據(jù)和橙。
原來我把application/x-www-form-urlencoded和multipart/form-data這兩種數(shù)據(jù)格式弄混了仔燕。在我自己寫頁面的時候,發(fā)現(xiàn)不定義enctype也可以提交魔招,但是服務器端我是用python 的resp.form來解析的晰搀,那時候我就發(fā)現(xiàn)解析不出來。
請求類似如下方式
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;
其次外恕,提交的數(shù)據(jù)按照key1=val1&key2=val2的方式進行編碼,key和val都進行了URL轉碼乡翅。
再次鳞疲,我們使用Ajax提交數(shù)據(jù)時,也是使用這種方式蠕蚜。
key1=val1&key2=val2這種編碼方式看著很眼熟尚洽,get方式提交數(shù)據(jù)的時候不也是這個樣子嗎?由此靶累,我覺得form-urlencoded作為post默認方式腺毫,不是偶然的,是和get一脈相承的挣柬。
multipart/form-data
這種方式用于上傳表單潮酒。作者的話太簡單,我來引述點其他資料凛忿。
http協(xié)議本身的原始方式不支持multipart/form-data澈灼,這個請求方式是在原始post方法上演變而來的。
- multipart/form-data 的基礎方法是post店溢,也就是說由post方法來組合實現(xiàn)的。
- multipart/form-data與post方法的不同之處:
1 multipart/form-data的基礎方法是post委乌,也就是說由post方法來組合實現(xiàn)的床牧。
2 multipart/form-data與post方法不同之處在于:請求頭,請求體遭贸。
3 multipart/form-data的請求頭必須包含一個特殊的頭信息:Content-Type,且值也必須規(guī)定為multipart/form-data戈咳,同時還需要規(guī)定一個內容分割符用于分割請求體的多個post的內容,如文件內容和文本內容自然要分割開來壕吹。具體的頭部信息如下:
Content-Type:multipart/form-data;boundary=${bound}
//${bound}是一個占位符著蛙,代表我們規(guī)定的分割符,分割符我們可以自己隨意規(guī)定耳贬。如“---------------------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協(xié)議詳解.pdf"
Content-Type:application/octet-stream
.....
這兩種方式都是瀏覽器原生支持的诫隅,現(xiàn)階段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請求數(shù)據(jù)的時候有兩種,傳json的話就是application/json,不傳json的話就是application/x-www-form-urlencoded
傳文件的話用multipart/form-data.