用 HTTP 提交資料,基本就這 5 種方式
網頁開發中,向服務端提交資料是一個基本功能,工作中會大量用 xhr/fetch 的 api 或者 axios 這種封裝了一層的庫來做。
可能大家都寫過很多 http/https 相關的程式碼,但是又沒有梳理下它們有哪幾種呢?
其實通過 http/https 向服務端傳遞資料的方式,基本可以分為 5 種:url param、query、form-urlencoded、form-data、json。
url param
Restful 的規範允許把引數寫在 url 中,比如:
http://guang.zxg/person/1111
這裡的 1111 就是路徑中的引數(url param),服務端框架或者單頁應用的路由都支援從 url 中取出引數。
query
通過 url 中 ?後面的用 & 分隔的字串傳遞資料。比如:
http://guang.zxg/person?name=guang&age=20
這裡的 name 和 age 就是 query 傳遞的資料。
其中非英文的字元和一些特殊字元要經過編碼,可以使用 encodeURLComponent 的 api,或者使用封裝了一層的 qeury-string 庫來處理。
const queryString = require('query-string'); queryString.stringify({ name: '光', age: 20 }); //?name=%E5%85%89&age=20
通過 URL 傳遞資料的方式就這 2種,後面 3 種是通過 body 傳遞資料的方式。
form-urlencoded
直接用 form 表單提交資料就是這種,它和 query 字串的方式的區別只是放在了 body 裡,然後指定下 content-type 是 application/x-www-form-urlencoded
。

因為也是 query 字串,所以也要用 encodeURIComponent 的 api 或者 query-string 庫處理下。
其實這種設計也很容易理解,get 是把資料拼成 query 字串放在 url 後面,於是設計表單的 post 提交方式的時候就直接用相同的方式把資料放在了 body 裡。
通過 & 分隔的 form-urlencoded 的方式需要對內容做 url encode,如果傳遞大量的資料,比如上傳檔案的時候就不是很合適了,因為檔案 encode 一遍的話太慢了,這時候就可以用 form-data。
form-data
form data 不再是通過 & 分隔資料,而是用 --------- + 一串數字做為分隔符。因為不是 url 的方式了,自然也不用再做 url encode。

form-data 需要指定 content type 為 multipart/form-data
,然後指定 boundary 也就是分割線。
body 裡面就是用 boundary 分割線分割的內容。
很明顯,這種方式適合傳輸檔案,而且可以傳輸多個檔案。
但是畢竟多了一些只是用來分隔的 boundary,所以請求體會增大。
json
form-urlencoded 需要對內容做 url encode,而 form data 則需要加很長的 boundary,兩種方式都有一些缺點。如果只是傳輸 json 資料的話,不需要用這兩種。
可以直接指定content type 為 application/json 就行:

我們平時傳輸 json 資料基本用的是這種。
這三種是通過 body 傳遞資料的方式。
總結
網頁開發中向服務端傳送資料是一個基本功能,常用的方式就 url param、query、form urlencoded、form data、json 這 5 種。
前 2 種是通過 url 傳遞資料的方式(需要對資料做 url encode),後 3 種是通過 body 傳遞資料。
form urlencoded 只是把 query 放在了 body 裡,同樣需要對資料做 url encoded,所以處理檔案就不合適了。(content type 要指定為 application/x-www-form-urlencoded
)
form data 是通過 boundary 分隔內容,不需要做 url encode,所以用來傳檔案很合適。但是如果不是傳檔案就沒必要用了,因為多了一些 boundary 字串比較佔空間。(content type 要指定為 multipart/form-data
)
json 是現在最常用的傳遞資料的方式,既不需要 url encoded,又不需要加沒必要的 boundary。(指定 content type 為 application/json
)。
當然,也可以指定別的 content type,比如 application/xml
、 text/plain
等,但一般不會用。
99% 情況下,我們都是通過這 5 種 http/https 的提交資料的方式和服務端互動的。
分享
收藏
點贊
在看
- 從根上理解 React Hooks 的閉包陷阱
- 談談我這些年對前端狀態管理的理解
- 幾個一看就會的 Chrome Devtools 小技巧
- 理清 HTTP 之下的 TCP 流程,讓你的 HTTP 水平更上一層
- 快速理解 TypeScript 的逆變和協變
- React Hooks 的實現必須依賴 Fiber 麼?
- 什麼?函式型別過載還可以動態生成?
- 編譯 ts 程式碼用 tsc 還是 babel?
- MobX 實現原理揭祕
- 私有屬性的 6 種實現方式,你用過幾種?
- 兩種給 Http 新增狀態的方式,都不完美
- 幾個一看就會的 TypeScript 小技巧
- Nest.js 是如何實現 AOP 架構的?
- React Hooks 的原理,有的簡單有的不簡單
- 位元組一面,面試官問我Vue3原始碼,我說……
- 從 IP 到 IP,聊聊計算機網路中那些“沒用的”知識
- 真實案例說明 TypeScript 型別體操的意義
- 能用 AST 搞明白的正則語法,就不需要看文件
- 粉絲破萬了,講講頭像背後的故事
- SSR 和前端編譯,在這點上是一樣的