用 HTTP 提交數(shù)據(jù),基本就這五種方式
網(wǎng)頁開發(fā)中,向服務端提交數(shù)據(jù)是一個基本功能,工作中會大量用 xhr/fetch 的 api 或者 axios 這種封裝了一層的庫來做。
可能大家都寫過很多 http/https 相關的代碼,但是又沒有梳理下它們有哪幾種呢?
其實通過 http/https 向服務端傳遞數(shù)據(jù)的方式,基本可以分為 5 種:url param、query、form-urlencoded、form-data、json。
url param
Restful 的規(guī)范允許把參數(shù)寫在 url 中,比如:
- http://guang.zxg/person/1111
這里的 1111 就是路徑中的參數(shù)(url param),服務端框架或者單頁應用的路由都支持從 url 中取出參數(shù)。
query
通過 url 中 ?后面的用 & 分隔的字符串傳遞數(shù)據(jù)。比如:
- http://guang.zxg/person?name=guang&age=20
這里的 name 和 age 就是 query 傳遞的數(shù)據(jù)。
其中非英文的字符和一些特殊字符要經(jīng)過編碼,可以使用 encodeURLComponent 的 api,或者使用封裝了一層的 qeury-string 庫來處理。
- const queryString = require('query-string');
- queryString.stringify({
- name: '光',
- age: 20
- });
- //?name=%E5%85%89&age=20
通過 URL 傳遞數(shù)據(jù)的方式就這 2種,后面 3 種是通過 body 傳遞數(shù)據(jù)的方式。
form-urlencoded
直接用 form 表單提交數(shù)據(jù)就是這種,它和 query 字符串的方式的區(qū)別只是放在了 body 里,然后指定下 content-type 是 application/x-www-form-urlencoded。
因為也是 query 字符串,所以也要用 encodeURIComponent 的 api 或者 query-string 庫處理下。
其實這種設計也很容易理解,get 是把數(shù)據(jù)拼成 query 字符串放在 url 后面,于是設計表單的 post 提交方式的時候就直接用相同的方式把數(shù)據(jù)放在了 body 里。
通過 & 分隔的 form-urlencoded 的方式需要對內(nèi)容做 url encode,如果傳遞大量的數(shù)據(jù),比如上傳文件的時候就不是很合適了,因為文件 encode 一遍的話太慢了,這時候就可以用 form-data。
form-data
form data 不再是通過 & 分隔數(shù)據(jù),而是用 --------- + 一串數(shù)字做為分隔符。因為不是 url 的方式了,自然也不用再做 url encode。
form-data 需要指定 content type 為 multipart/form-data,然后指定 boundary 也就是分割線。
body 里面就是用 boundary 分割線分割的內(nèi)容。
很明顯,這種方式適合傳輸文件,而且可以傳輸多個文件。
但是畢竟多了一些只是用來分隔的 boundary,所以請求體會增大。
json
form-urlencoded 需要對內(nèi)容做 url encode,而 form data 則需要加很長的 boundary,兩種方式都有一些缺點。如果只是傳輸 json 數(shù)據(jù)的話,不需要用這兩種。
可以直接指定content type 為 application/json 就行:
我們平時傳輸 json 數(shù)據(jù)基本用的是這種。
這三種是通過 body 傳遞數(shù)據(jù)的方式。
總結
網(wǎng)頁開發(fā)中向服務端傳送數(shù)據(jù)是一個基本功能,常用的方式就 url param、query、form urlencoded、form data、json 這 5 種。
前 2 種是通過 url 傳遞數(shù)據(jù)的方式(需要對數(shù)據(jù)做 url encode),后 3 種是通過 body 傳遞數(shù)據(jù)。
form urlencoded 只是把 query 放在了 body 里,同樣需要對數(shù)據(jù)做 url encoded,所以處理文件就不合適了。(content type 要指定為 application/x-www-form-urlencoded)
form data 是通過 boundary 分隔內(nèi)容,不需要做 url encode,所以用來傳文件很合適。但是如果不是傳文件就沒必要用了,因為多了一些 boundary 字符串比較占空間。(content type 要指定為 multipart/form-data)
json 是現(xiàn)在最常用的傳遞數(shù)據(jù)的方式,既不需要 url encoded,又不需要加沒必要的 boundary。(指定 content type 為 application/json)。
當然,也可以指定別的 content type,比如 application/xml、text/plain 等,但一般不會用。
99% 情況下,我們都是通過這 5 種 http/https 的提交數(shù)據(jù)的方式和服務端交互的。