from屬性EncType提交數(shù)據(jù)的格式詳解—在angular中的應用


from屬性EncType提交數(shù)據(jù)的格式詳解—在angular中的應用

我們知道,HTTP 協(xié)議是以 ASCII 碼傳輸渣刷,建立在 TCP/IP 協(xié)議之上的應用層規(guī)范。規(guī)范把 HTTP 請求分為三個部分:狀態(tài)行、請求頭、消息主體汰具。類似于下面這樣:

轉(zhuǎn)載請注明出處:http://www.zhoulujun.cn/zhoulujun/html/webfront/SGML/web/2017_0719_8034.html

協(xié)議規(guī)定 POST 提交的數(shù)據(jù)必須放在消息主體(entity-body)中,但協(xié)議并沒有規(guī)定數(shù)據(jù)必須使用什么編碼方式菱魔。實際上留荔,開發(fā)者完全可以自己決定消息主體的格式,只要最后發(fā)送的 HTTP 請求滿足上面的格式就可以澜倦。

但是存谎,數(shù)據(jù)發(fā)送出去,還要服務端解析成功才有意義肥隆。一般服務端語言如 php既荚、python 等,以及它們的 framework栋艳,都內(nèi)置了自動解析常見數(shù)據(jù)格式的功能恰聘。服務端通常是根據(jù)請求頭(headers)中的 Content-Type 字段來獲知請求中的消息主體是用何種方式編碼,再對主體進行解析吸占。所以說到 POST 提交數(shù)據(jù)方案晴叨,包含了 Content-Type 和消息主體編碼方式兩部分。

我們悉知矾屯,form表單屬性EncType表明提交數(shù)據(jù)的格式

用 Enctype 屬性指定將數(shù)據(jù)回發(fā)到服務器時瀏覽器使用的編碼類型兼蕊。

下邊是說明:

application/x-www-form-urlencoded: 窗體數(shù)據(jù)被編碼為名稱/值對。這是標準的編碼格式件蚕。一般默認為application/x-www-form-urlencoded孙技。

multipart/form-data: 窗體數(shù)據(jù)被編碼為一條消息,頁上的每個控件對應消息中的一個部分排作。

text/plain: 窗體數(shù)據(jù)以純文本形式進行編碼牵啦,其中不含任何控件或格式字符。

當action為get時候妄痪,瀏覽器用x-www-form-urlencoded的編碼方式把form數(shù)據(jù)轉(zhuǎn)換成一個字串(name1=value1&name2=value2...)哈雏,然后把這個字串a(chǎn)ppend到url后面,用?分割衫生,加載這個新的url裳瘪。

當action為post時候,瀏覽器把form數(shù)據(jù)封裝到http body中罪针,然后發(fā)送到server彭羹。

如果沒有type=file的控件,用默認的application/x-www-form-urlencoded就可以了站故。

但是如果有type=file的話皆怕,就要用到multipart/form-data了。瀏覽器會把整個表單以控件為單位分割西篓,并為每個部分加上Content-Disposition(form-data或者file),Content-Type(默認為text/plain),name(控件name)等信息愈腾,并加上分割符(boundary)

在Form元素的語法中,EncType表明提交數(shù)據(jù)的格式 用 Enctype 屬性指定將數(shù)據(jù)回發(fā)到服務器時瀏覽器使用的編碼類型岂津。 下邊是說明: application/x-www-form-urlencoded: 窗體數(shù)據(jù)被編碼為名稱/值對虱黄。這是標準的編碼格式。 multipart/form-data: 窗體數(shù)據(jù)被編碼為一條消息吮成,頁上的每個控件對應消息中的一個部分橱乱。 text/plain: 窗體數(shù)據(jù)以純文本形式進行編碼,其中不含任何控件或格式字符粱甫。

application/x-www-form-urlencoded

這應該是最常見的 POST 提交數(shù)據(jù)的方式了泳叠。瀏覽器的原生

首先,Content-Type 被指定為 application/x-www-form-urlencoded茶宵;其次危纫,提交的數(shù)據(jù)按照 key1=val1&key2=val2 的方式進行編碼,key 和 val 都進行了 URL 轉(zhuǎn)碼乌庶。大部分服務端語言都對這種方式有很好的支持种蝶。例如 PHP 中,$_POST['title'] 可以獲取到 title 的值瞒大,$_POST['sub'] 可以得到 sub 數(shù)組螃征。

很多時候,我們用 Ajax 提交數(shù)據(jù)時透敌,也是使用這種方式盯滚。例如 JQuery 和 QWrap 的 Ajax,Content-Type 默認值都是「application/x-www-form-urlencoded;charset=utf-8」酗电。

multipart/form-data

這又是一個常見的 POST 數(shù)據(jù)提交的方式淌山。我們使用表單上傳文件時,必須讓

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 用于分割不同的字段泼疑,為了避免與正文內(nèi)容重復,boundary 很長很復雜荷荤。然后 Content-Type 里指明了數(shù)據(jù)是以 multipart/form-data 來編碼退渗,本次請求的 boundary 是什么內(nèi)容。消息主體里按照字段個數(shù)又分為多個結(jié)構(gòu)類似的部分蕴纳,每部分都是以--boundary開始会油,緊接著是內(nèi)容描述信息,然后是回車古毛,最后是字段具體內(nèi)容(文本或二進制)翻翩。如果傳輸?shù)氖俏募夹恚€要包含文件名和文件類型信息。消息主體最后以--boundary--標示結(jié)束嫂冻。關于 multipart/form-data 的詳細定義胶征,請前往 rfc1867 查看。

這種方式一般用來上傳文件桨仿,各大服務端語言對它也有著良好的支持睛低。

上面提到的這兩種 POST 數(shù)據(jù)的方式,都是瀏覽器原生支持的服傍,而且現(xiàn)階段標準中原生

隨著越來越多的 Web 站點钱雷,尤其是 WebApp,全部使用 Ajax 進行數(shù)據(jù)交互之后吹零,我們完全可以定義新的數(shù)據(jù)提交方式罩抗,給開發(fā)帶來更多便利。

application/json

application/json 這個 Content-Type 作為響應頭大家肯定不陌生灿椅。實際上澄暮,現(xiàn)在越來越多的人把它作為請求頭,用來告訴服務端消息主體是序列化后的 JSON 字符串阱扬。由于 JSON 規(guī)范的流行泣懊,除了低版本 IE 之外的各大瀏覽器都原生支持 JSON.stringify,服務端語言也都有處理 JSON 的函數(shù)麻惶,使用 JSON 不會遇上什么麻煩馍刮。

JSON 格式支持比鍵值對復雜得多的結(jié)構(gòu)化數(shù)據(jù),這一點也很有用窃蹋。記得我?guī)啄昵白鲆粋€項目時卡啰,需要提交的數(shù)據(jù)層次非常深,我就是把數(shù)據(jù) JSON 序列化之后來提交的警没。不過當時我是把 JSON 字符串作為 val匈辱,仍然放在鍵值對里,以 x-www-form-urlencoded 方式提交杀迹。

Google 的 AngularJS 中的 Ajax 功能亡脸,默認就是提交 JSON 字符串。例如下面這段代碼:

var?data?=?{'title':'test',?'sub'?:?[1,2,3]};

$http.post(url,?data).success(function(result)?{

...

});

最終發(fā)送的請求是:

BASHPOST?http://www.example.com?HTTP/1.1

Content-Type:?application/json;charset=utf-8

{"title":"test","sub":[1,2,3]}

這種方案树酪,可以方便的提交復雜的結(jié)構(gòu)化數(shù)據(jù)浅碾,特別適合 RESTful 的接口。各大抓包工具如 Chrome 自帶的開發(fā)者工具续语、Firebug垂谢、Fiddler,都會以樹形結(jié)構(gòu)展示 JSON 數(shù)據(jù)疮茄,非常友好滥朱。但也有些服務端語言還沒有支持這種方式根暑,例如 php 就無法通過 $_POST 對象從上面的請求中獲得內(nèi)容。這時候徙邻,需要自己動手處理下:在請求頭中 Content-Type 為 application/json 時排嫌,從php://input里獲得原始輸入流,再json_decode成對象鹃栽。一些 php 框架已經(jīng)開始這么做了躏率。

angularjs默認就是采用這種模式躯畴,如果需要民鼓,更改angular請求模式,一般請求:

$http({

method:?'POST',

cache:?false,

data:?data,

headers:?{?'Content-Type':?'application/x-www-form-urlencoded;?charset=UTF-8'},

transformRequest:?function(obj)?{

console.log('?$httpProvider.defaults.transformRequest?=?function(obj)?{');

console.log(obj);

var?str?=?[];

for?(var?p?in?obj)

str.push(encodeURIComponent(p)?+?"="?+?encodeURIComponent(obj[p]));

return?str.join("&");

},

url:?"syf-merchant/uploadMerchantRegPic"

}).success(function?(response)?{

}).error(function?()?{

CommonService.showMessage('上傳失敗蓬抄,請稍后再試')

})

};

當然丰嘉,也可以,直接攔截所有請求嚷缭,轉(zhuǎn)換:

/*?我的攔截器?*/

$httpProvider.defaults.headers.post['Content-Type']?=?'application/x-www-form-urlencoded;charset=UTF-8';

$httpProvider.defaults.transformRequest?=?function(obj)?{

console.log('?$httpProvider.defaults.transformRequest?=?function(obj)?{');

console.log(obj);

var?str?=?[];

for?(var?p?in?obj)

str.push(encodeURIComponent(p)?+?"="?+?encodeURIComponent(obj[p]));

return?str.join("&");

};

參考文章:

https://imququ.com/post/four-ways-to-post-data-in-http.html

http://www.cnblogs.com/sunxucool/archive/2012/12/11/2813113.html

轉(zhuǎn)載請注明出處:http://www.zhoulujun.cn/zhoulujun/html/webfront/SGML/web/2017_0719_8034.html

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末饮亏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子阅爽,更是在濱河造成了極大的恐慌路幸,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件付翁,死亡現(xiàn)場離奇詭異简肴,居然都是意外死亡,警方通過查閱死者的電腦和手機百侧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門砰识,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人佣渴,你說我怎么就攤上這事辫狼。” “怎么了辛润?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵膨处,是天一觀的道長。 經(jīng)常有香客問我砂竖,道長灵迫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任晦溪,我火速辦了婚禮瀑粥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘三圆。我一直安慰自己狞换,他們只是感情好避咆,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著修噪,像睡著了一般查库。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上黄琼,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天樊销,我揣著相機與錄音,去河邊找鬼脏款。 笑死围苫,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的撤师。 我是一名探鬼主播剂府,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼剃盾!你這毒婦竟也來了腺占?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤痒谴,失蹤者是張志新(化名)和其女友劉穎衰伯,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體积蔚,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡意鲸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了库倘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片临扮。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖教翩,靈堂內(nèi)的尸體忽然破棺而出杆勇,到底是詐尸還是另有隱情,我是刑警寧澤饱亿,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布蚜退,位于F島的核電站,受9級特大地震影響彪笼,放射性物質(zhì)發(fā)生泄漏钻注。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一配猫、第九天 我趴在偏房一處隱蔽的房頂上張望幅恋。 院中可真熱鬧,春花似錦泵肄、人聲如沸捆交。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽品追。三九已至玄括,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間肉瓦,已是汗流浹背遭京。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留泞莉,地道東北人哪雕。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像戒财,于是被迫代替她去往敵國和親热监。 傳聞我的和親對象是個殘疾皇子捺弦,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容