前端最基礎的就是 HTML+CSS+Javascript。掌握了這三門技術就算入門,但也僅僅是入門,現在前端開發的定義已經遠遠不止這些。前端小課堂(HTML/CSS/JS),本著提升技術水平,打牢基礎知識的中心思想,我們開課啦(每週四)。
axios
日常使用上,感覺不如 $.ajax
但是我之前使用的時候不是改入參就是改方法反正是都解決了。
我也知道問題出在 content-type
上。
就是記不住,這不前幾天後臺專案起了個新的服務。
之前用的構建開發工具用的是 proxy
代理,不知道有老哥用過沒,好幾年前初次開發的時候就不更新了,還有 bug
。
索性換 axios
代理一下吧,然後報錯了。好吧,我的鍋,我認真總結,保證我不忘了。
今天講什麼?
-
content-type
是什麼 -
MIME
對照表 -
axios
為什麼感覺不如$.ajax
- 帶你領略
axios
正確開啟方式
content-type
是什麼
Content-Type
實體頭部用於指示資源的 MIME
型別 media type
。
在響應中,用來描述服務端實際傳送給客戶端的資料的型別。
在請求中,比如 POST
請求,是指客戶端給伺服器實際傳送的資料的型別。
雙方根據這個值,來選擇適合的方式解析資料。
MIME
型別組成方式
type/subtype
,如application/json
、text/html
、text/plain
對大小寫不敏感,但是習慣寫小寫。
content-type
組成方式
Content-Type:media-type; charset
,如Content-Type: text/html; charset=utf-8
表單中的應用
<form action="/" method="post" enctype="multipart/form-data">
想上傳檔案的時候<form action="/" method="post" enctype="application/x-www-form-urlencoded">
預設
為什麼想上傳檔案不能用第二個呢?帶著你的問題往後看吧
MIME
對照表
MIME
分類
type關鍵詞 | 描述 | 示例 |
text | 文字。複製貼上的裡面常見。 |
text/html html頁面, text/css css檔案,text/plain 通用文字(預設格式) |
image | 圖片。input.files[0].type 返回的時候用於判斷型別。input accept="image/*" 允許選擇所有圖片檔案 |
image/png png圖片, image/jpeg jpg圖片 |
audio | 音訊。同上 |
audio/wav ,audio/mpeg mp3檔案 |
video | 影片。同上 |
video/mp4 MP4檔案 |
application | 二進位制資料 |
application/octet-stream 通用型別(預設格式),application/pdf
|
multipart | 複合型別 | multipart/form-data |
常見 MIME
key | 描述 |
application/octet-stream | 預設值,或者可以理解為未知的應用程式檔案。瀏覽器會像對待設定了 HTTP 頭 Content-Disposition 值為 attachment 的檔案一樣來對待這類檔案。(微信下載檔案) |
text/html | 可以理解為 html、xml 檔案。 |
text/plain | 預設值,也可以理解為未知格式的文字檔案。文字檔案嘛,沒格式就只看字也不是啥大問題 |
image/png | 常見圖片型別,一般上傳圖片的時候判斷 |
image/jpeg | 常見圖片型別,一般上傳圖片的時候判斷 |
image/gif | 常見圖片型別,一般上傳圖片的時候判斷 |
multipart/byteranges | 用於把部分的響應報文傳送回瀏覽器。常見於請求影片資源返回206狀態碼 |
application/json | JSON 格式 |
multipart/form-data | 用於帶檔案上傳的表單提交。作為多部分文件格式,由邊界線(一個由'--'開始的字串)劃分出的不同部分組成。每一部分有自己的實體,以及自己的 HTTP 請求頭,Content-Disposition 和 Content-Type 。 |
application/x-www-form-urlencoded |
普通的 get&post 請求。資料被編碼為鍵/值對。(a=1&b=2) 這是標準的編碼格式。 |
axios
為什麼感覺不如 $.ajax
(同樣程式碼 jquery 好使,axios 不好使,axios 有 bug 吧)-這個應該是我聽到最多的吐槽了。測試地址
axios 與 $.ajax 設計思路、或者說歷史場景
-
jquery
非常棒,他存在解決了各個瀏覽器版本不一致的問題,提供了統一的api
,極大的簡化了我們的操作。 -
axios
擁抱現代瀏覽器,提供跨平臺(Node發請求)、Promise
等。
get 請求
對於 get 請求其實沒有太多說的,請求的引數會拼在 url 上,如 https://www.lilnong.top/CORS/lnong?a=1&b=2
,其中 a=1&b=2
就是帶過去的引數
同樣兩個使用,我們會發現 axios
的沒有帶過去引數。
這個時候兄弟們就開始說,我寫了為什麼傳不過去。垃圾垃圾。針對上面的問題兄弟們罵完之後,還是要解決問題的。
- 手動拼寫,兄弟也是虎的可以
-
qs
、$.param({a:1,b:2})
等類庫解決處理問題,然後手動拼接 - 正確答案(axios 是使用
params
來傳送get
的資料的)
post 請求
對於 post 請求來說就有好幾種情況了
-
application/x-www-form-urlencoded
這種情況等於把 get 方式的引數拿到 請求體中存放。編譯格式是一模一樣的。 -
application/json
請求體中就是如下的JSON字串{a:1,b:2}
-
multipart/form-data
請求體中就是這種塊的結構。
好,那我們接著看兄弟們為什麼要吐槽。同樣,我 ajax 怎麼好使,axios ****
-
data
不行,我們換params
,嗯這裡其實分為兩個情況- 後臺大哥說收到了,嗯,post 也是 params的結論就出來了
- 過幾天另一個後臺大哥說收不到。很奇怪,又開始揪頭髮。
- 這裡說一下為什麼有的時候能收到,有的時候不行。首先 params 帶過去的引數會拼寫在 url 上。如果嚴格來按規定做的話,他就是拿body 的資訊就導致拿不到。不按規定來,url的構建一次,body的覆蓋一次,就導致拿到了。
- 有的人比較機靈,換
params
發現不怎麼好使,突然發現官網的例子,我來試一試。後臺大哥怎麼還收不到?這裡其實content-type
被改成了application/json
。一般來說老後臺都不會適配這種格式。axios({method:'post'}) 也是這種格式
- 沒辦法了?嗯,他們又開始自己拼接。嗯,這次有混過去了
-
transformRequest
大法,我這個方法裡面,給他處理一番。
-
FormData
大法好,精準識別,也算是正確的表單提交。
-
URLSearchParams
方案等同於Qs
的類庫,只不過是瀏覽器支援的,當然相容性也不怎麼樣
帶你領略 axios
正確開啟方式
- 使用
get
要用params
來傳送請求 -
使用
post
要用data
來傳送請求- 預設為
application/json
格式 - 可以透過
FormData
來進行修改 - 更建議全域性
transformRequest
的方案
- 預設為
-
axios
支援Promise
axios.get('/user?ID=12345') .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
-
axios
支援 Node 環境 -
配置預設值,方案1更痛快,可以增加一些通用的
headers
。-
全域性的 axios 預設值
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
-
例項預設值
// 建立例項時設定配置的預設值 var instance = axios.create({ baseURL: 'https://api.example.com' }); // 在例項已建立後修改預設值 instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;
-
-
攔截器,可以攔截錯誤,進行上報。或者列印日誌。
// 新增響應攔截器 axios.interceptors.response.use(function (response) { // 對響應資料做點什麼 return response; }, function (error) { // 對響應錯誤做點什麼 return Promise.reject(error); });
總結
content-type
很重要,在 req 中是告知伺服器應該用什麼樣的格式去解析資料,rsp 中是讓瀏覽器端去如何解析資料。
根據對應的型別,傳對應的格式,才可以正確的收發。