最合適的Ajax內(nèi)容編碼類型
原文地址:我的博客
背景
在公司開發(fā)的一個(gè)頁面的[Ajax][Ajax]請(qǐng)求使用了contentType:application/json
酵幕,被后臺(tái)的同事要求用x-www-form-urlencoded
,撕逼撕不過他睹逃,趕緊回來學(xué)學(xué)知識(shí)迁霎。
引入
contentType
是指http/https發(fā)送信息至服務(wù)器時(shí)的內(nèi)容編碼類型罕扎,contentType
用于表明發(fā)送數(shù)據(jù)流的類型咨跌,服務(wù)器根據(jù)編碼類型使用特定的解析方式摹恰,獲取數(shù)據(jù)流中的數(shù)據(jù)辫继。內(nèi)容編碼類型的作用怒见,有點(diǎn)像本地文件的后綴名。
問題來了
發(fā)送Ajax請(qǐng)求最合適的內(nèi)容編碼類型是什么姑宽?
常見的contentType
x-www-form-urlencoded
這是Jquery/Zepto Ajax默認(rèn)的提交類型遣耍。最簡(jiǎn)例子為:
let userInfo = {
name: 'CntChen',
info: 'Front-End',
}
$.ajax({
url: 'https://github.com',
type: 'POST',
data: userInfo,
success: (data) => {},
});
此時(shí)默認(rèn)的提交的contentType
為application/x-www-form-urlencoded
,此時(shí)提交的數(shù)據(jù)將會(huì)格式化成:
name=CntChen&info=Front-End
HTML的form
表單默認(rèn)的提交編碼類型也是x-www-form-urlencoded
,可能這就是Jquery/Zepto等類庫(其實(shí)是Ajax:XMLHttpRequest)也默認(rèn)使用contentType:x-www-form-urlencoded
的原因,畢竟表單的歷史比Ajax早多了炮车。--我猜的舵变,待驗(yàn)證
如果請(qǐng)求類型type
是GET
,格式化的字符串將直接拼接在url后發(fā)送到服務(wù)端;如果請(qǐng)求類型是POST
瘦穆,格式化的字符串將放在http body的Form Data中發(fā)送纪隙。
json
使用json內(nèi)容編碼發(fā)送數(shù)據(jù),最簡(jiǎn)例子為:
let userInfo = {
name: 'CntChen',
Info: 'Front-End',
}
$.ajax({
url: 'https://github.com',
contentType: 'application/json',
type: 'POST',
data: JSON.stringify(userInfo),
success: (data) => {},
});
最主要的不同有3點(diǎn):
- 需要顯式指定
contentType
為application/json
扛或,覆蓋默認(rèn)的contentType - 需要使用
JSON.stringify
序列化需要提交的數(shù)據(jù)對(duì)象绵咱,序列化的結(jié)果為:
{"name":"CntChen","info":"Front-End"}
- 提交的類型不能為
GET
,使用GET
的話,數(shù)據(jù)會(huì)在url中發(fā)送熙兔,此時(shí)就無法以json字符串的編碼發(fā)送
multipart/form-data
When you are writing client-side code, all you need to know is use multipart/form-data when your form includes any < input type="file" > elements.
-- [multipart/form-data][multipart/form-data]
multipart/form-data
主要用于傳輸文件數(shù)據(jù)的悲伶。
JS對(duì)象編碼
對(duì)于扁平的參數(shù)對(duì)象,使用x-www-form-urlencoded
或json
并沒有大的差別住涉,后臺(tái)都可以處理成對(duì)象麸锉,并且數(shù)據(jù)編碼后的長(zhǎng)度差別不大。
但是對(duì)于對(duì)象中嵌套對(duì)象秆吵,或對(duì)象字段包含數(shù)組淮椰,此時(shí)兩種內(nèi)容編碼方式就有較大差別。
對(duì)象嵌套
{
userInfo :{
name: 'CntChen',
info: 'Front-End',
login: true,
},
}
- to x-www-form-urlencoded
(1)
userInfo[name]=CntChen&userInfo[info]=Front-End&userInfo[login]=true
- to json
(2)
{"userInfo":{"name":"CntChen","Info":"Front-End","login":true}}
對(duì)象字段為數(shù)組
{
authors:[
{
name: 'CntChen',
info: 'Front-End',
},
{
name: 'Eva',
info: 'Banker',
}
],
}
- to x-www-form-urlencoded
(3)
authors[0][name]=CntChen&authors[0][info]=Front-End&authors[1][name]=Eva&authors[1][info]=Banker
- to json
(4)
{"authors":[{"name":"CntChen","info":"Front-End"},{"name":"Eva","info":"Banker"}]}
可見:x-www-form-urlencoded
是先將對(duì)象鋪平纳寂,然后使用key=value
的方式主穗,用&
作為間隔。對(duì)于嵌套對(duì)象的每個(gè)字段毙芜,都要傳輸其前綴忽媒,如(1)
中的userInfo
重復(fù)傳輸了3次;(3)
中authors傳輸了4次。
如果對(duì)象是多重嵌套的腋粥,或者嵌套對(duì)象的字段較多晦雨,x-www-form-urlencoded
會(huì)產(chǎn)生更多冗余信息。同時(shí)隘冲,x-www-form-urlencoded
可讀性不如json
字符串闹瞧。
回答問題:json最好
較小的傳輸量
從前文可以看出,使用json字符串的形式展辞,可以減少冗余字段的傳輸奥邮,減少請(qǐng)求的數(shù)據(jù)量。
補(bǔ)充:可能你會(huì)覺得
(4)
中數(shù)組內(nèi)的name
和info
也傳輸了多次,是不是也存在冗余洽腺?其實(shí)這不是冗余脚粟。因?yàn)閷?duì)數(shù)組中的各對(duì)象,并不要求其具有相同的字段(數(shù)組中的對(duì)象并不是結(jié)構(gòu)化的)蘸朋,所以不能忽略“相同”的字段名核无。使用x-www-form-urlencoded
編碼方式,數(shù)組內(nèi)對(duì)象的字段也是重復(fù)傳輸藕坯。
請(qǐng)求與返回統(tǒng)一
目前許多前后端交互的返回?cái)?shù)據(jù)是json字符串团南,這可能是考慮較小的傳輸量而作出的選擇。同時(shí)堕担,ES3.1添加了JSON對(duì)象已慢,許多瀏覽器可以[直接使用JSON對(duì)象][Can I use JSON]曲聂,可以將json字符串解析為JS對(duì)象(JSON.parse
),將JS對(duì)象編碼為json字符串(JSON.stringify
);
所以使用json編碼請(qǐng)求數(shù)據(jù)霹购,其編碼解碼非常方便,并且可以保持與后臺(tái)返回?cái)?shù)據(jù)的格式一致朋腋。
一致是一件很美好的事情齐疙。
框架的支持
目前Mvvm的前端框架如React,網(wǎng)絡(luò)請(qǐng)求通常是提交一個(gè)JS對(duì)象(傳輸?shù)臅r(shí)候編碼為json字符串)旭咽。后臺(tái)服務(wù)器如Koa贞奋,接收請(qǐng)求和響應(yīng)的數(shù)據(jù)是json字符串。
可讀性高
可讀性高是json格式[自帶buff][JSON]穷绵。
結(jié)論
趕緊使用contentType=applications/json
轿塔。
References
- Ajax
http://css88.com/doc/zeptojs_api/#$.ajax
[Ajax]:http://css88.com/doc/zeptojs_api/#$.ajax
- x-www-form-urlencoded VS json - Pros and Cons. And Vulns.
http://homakov.blogspot.in/2012/06/x-www-form-urlencoded-vs-json-pros-and.html
[x-www-form-urlencoded VS json]:http://homakov.blogspot.in/2012/06/x-www-form-urlencoded-vs-json-pros-and.html
- What does enctype='multipart/form-data' mean?
http://stackoverflow.com/questions/4526273/what-does-enctype-multipart-form-data-mean
[multipart/form-data]:http://stackoverflow.com/questions/4526273/what-does-enctype-multipart-form-data-mean
- Can I use JSON
http://caniuse.com/#search=JSON
[Can I use JSON]:http://caniuse.com/#search=JSON
- JSON