最合適的Ajax內容編碼類型

最合適的Ajax內容編碼類型

原文地址:個人博客php

背景

在公司開發的一個頁面的Ajax請求使用了contentType:application/json,被後臺的同事要求用x-www-form-urlencoded,撕逼撕不過他,趕忙回來學學知識。css

引入

contentType是指http/https發送信息至服務器時的內容編碼類型contentType用於代表發送數據流的類型,服務器根據編碼類型使用特定的解析方式,獲取數據流中的數據。內容編碼類型的做用,有點像本地文件的後綴名。html

問題來了

發送Ajax請求最合適的內容編碼類型是什麼?前端

常見的contentType

x-www-form-urlencoded

這是Jquery/Zepto Ajax默認的提交類型。最簡例子爲:git

let userInfo = {
 name: 'CntChen',
 info: 'Front-End',
}

$.ajax({
  url: 'https://github.com',
  type: 'POST',
  data: userInfo,
  success: (data) => {},
});

此時默認的提交的contentTypeapplication/x-www-form-urlencoded,此時提交的數據將會格式化成:github

name=CntChen&info=Front-End

HTML的form表單默認的提交編碼類型也是x-www-form-urlencoded,可能這就是Jquery/Zepto等類庫(實際上是Ajax:XMLHttpRequest)也默認使用contentType:x-www-form-urlencoded的緣由,畢竟表單的歷史比Ajax早多了。--我猜的,待驗證ajax

若是請求類型typeGET,格式化的字符串將直接拼接在url後發送到服務端;若是請求類型是POST,格式化的字符串將放在http body的Form Data中發送。json

json

使用json內容編碼發送數據,最簡例子爲:後端

let userInfo = {
 name: 'CntChen',
 Info: 'Front-End',
}

$.ajax({
  url: 'https://github.com',
  contentType: 'application/json',
  type: 'POST',
  data: JSON.stringify(userInfo),
  success: (data) => {},
});

最主要的不一樣有3點:api

  • 須要顯式指定contentTypeapplication/json,覆蓋默認的contentType

  • 須要使用JSON.stringify序列化須要提交的數據對象,序列化的結果爲:

{"name":"CntChen","info":"Front-End"}
  • 提交的類型不能爲GET,使用GET的話,數據會在url中發送,此時就沒法以json字符串的編碼發送

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主要用於傳輸文件數據的。

JS對象編碼

對於扁平的參數對象,使用x-www-form-urlencodedjson並無大的差異,後臺均可以處理成對象,而且數據編碼後的長度差異不大。
可是對於對象中嵌套對象,或對象字段包含數組,此時兩種內容編碼方式就有較大差異。

格式化demo

對象嵌套

{
    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}}

對象字段爲數組

{
    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是先將對象鋪平,而後使用key=value的方式,用&做爲間隔。對於嵌套對象的每一個字段,都要傳輸其前綴,如(1)中的userInfo重複傳輸了3次;(3)中authors傳輸了4次。
若是對象是多重嵌套的,或者嵌套對象的字段較多,x-www-form-urlencoded會產生更多冗餘信息。同時,x-www-form-urlencoded可讀性不如json字符串。

回答問題:json最好

較小的傳輸量

從前文能夠看出,使用json字符串的形式,能夠減小冗餘字段的傳輸,減小請求的數據量。

補充:可能你會以爲(4)中數組內的nameinfo也傳輸了屢次,是否是也存在冗餘?其實這不是冗餘。由於對數組中的各對象,並不要求其具備相同的字段(數組中的對象並非結構化的),因此不能忽略「相同」的字段名。使用x-www-form-urlencoded編碼方式,數組內對象的字段也是重複傳輸。

請求與返回統一

目前許多先後端交互的返回數據是json字符串,這多是考慮較小的傳輸量而做出的選擇。同時,ES3.1添加了JSON對象,許多瀏覽器能夠直接使用JSON對象,能夠將json字符串解析爲JS對象(JSON.parse),將JS對象編碼爲json字符串(JSON.stringify);
因此使用json編碼請求數據,其編碼解碼很是方便,而且能夠保持與後臺返回數據的格式一致。
一致是一件很美好的事情。

框架的支持

目前Mvvm的前端框架如React,網絡請求一般是提交一個JS對象(傳輸的時候編碼爲json字符串)。後臺服務器如Koa,接收請求和響應的數據是json字符串。

可讀性高

可讀性高是json格式自帶buff

結論

趕忙使用contentType=applications/json

References

  • Ajax

http://css88.com/doc/zeptojs_...$.ajax

  • x-www-form-urlencoded VS json - Pros and Cons. And Vulns.

http://homakov.blogspot.in/20...

  • What does enctype='multipart/form-data' mean?

http://stackoverflow.com/ques...

  • Can I use JSON

http://caniuse.com/#search=JSON

  • JSON

http://www.json.org/

END

相關文章
相關標籤/搜索