axios基於es6的promise機制。Axios是一個基於promise的HTTP庫,類似於jQuery的ajax,用於http請求。Axios支援Promise API,在瀏覽器中傳送XMLHttpRequests請求,在node.js中傳送http請求;也可以攔截請求與響應,或轉換請求資料和響應資料。
如何快速入門VUE3.0:進入學習
本教學操作環境:windows7系統、ECMAScript 6版、Dell G3電腦。
axios
是目前前端使用非常廣泛的網路請求庫,包括Vue作者也是推薦在vue
中使用axios
;
它是一個封裝好的http請求庫,他是基於es6的promise機制實現的。
瀏覽器基於XMLHttpRequest物件封裝的,跟Ajax一樣,只不過他們開放的API使用有差別而已;
XMLHttpRequests
請求;node.js
中傳送 http
請求;Promise API
;取消請求
自動轉換JSON資料
使用者端支援防禦XSRF
使用 @vue/cli 4.5.13
版本建立一個只包含vue
的專案,建立完成之後安裝npm install axios
庫
所以整個專案的環境看起來就是這樣
當然,並不是說axios
不能夠在非 vue
的環境下使用,這裡我只是為了寫程式碼方便,普通的,使用瀏覽器 script
標籤 引入 axios
,在window
物件上就會有一個 axios
物件,這樣你在瀏覽器環境使用和我在vue
中使用起來就是完全一致的了。
看起來就像這樣:
這個網址學習http的時候大家應該都會聽說,對這個網址發請求,你傳送請求的內容會原樣的響應回來。
我們先看一下官方檔案給我們介紹的 axios api
列表
axios(config)axios(url[, config]) ----------------------分割線---------------------- axios.request(config) axios.get(url[, config]) axios.delete(url[, config]) axios.head(url[, config]) axios.options(url[, config]) axios.post(url[, data[, config]]) axios.put(url[, data[, config]]) axios.patch(url[, data[, config]])
分割線前面的方法,官方給了範例,分割線後面的方法,官方只是提了一下。
看到這裡可能還有點懵,寫點程式碼就立刻能看清楚拉。
根據axios
的官方檔案。我們先來簡單的發起一個 get
方法吧。
在app.vue
中,我們引入axios
,並且使用axios
攜帶引數傳送了一個get
請求。
我們先來看一下瀏覽器的網路請求
可以看到,我們發出的請求是成功了的。我們現在再來看一下我們 then中列印出來的響應結果。
我們發現then
中,列印出來的東西好像比我們網路請求的返回值內容要多。但是data
這個對應的值就是我們請求返回的結果。
ok
。到現在,我們是可以使用axios
傳送網路請求了。但是現在我們還是有很多的疑問。
axios({})
這個方法能發出一個網路請求,但是方法傳入的物件是什麼意思呢?
then
列印出來的 res
返回值中,為什麼會多了很多其他的引數?
axios
的官方檔案中已經給出了很多的介紹了。當然如果你是萌新,可能看起來會特別難受,啊,我就簡單學一個axios
,有這麼多東西要記嗎?
當然不是啦!我現在就來簡單的 使用我的理解翻譯一些 常用的設定
{ // url(常用) 表示我們用來發請求的地址 url: '/user', // method(常用) 表示我們用來發請求的方法,預設是get method: 'get', // baseURL(常用) 表示我們用來發請求跟 URL,最終發起請求的地址是 baseURL+url baseURL: 'https://some-domain.com/api/', // headers(常用) 設定我們發起的網路請求的請求頭,通常是攜帶token用來鑑權 headers: {'X-Requested-With': 'XMLHttpRequest'}, // params(常用) 這裡設定的物件會作為引數拼接到url上 ?username=xiaomin&password=123456 // 通常是 get請求攜帶引數的地方(重要) params: { username: 'xiaomin', password: '123456' }, // data(常用) data中的引數會被放到請求體中 // 通常是 post,put,delete請求攜帶引數的地方(重要) // 可以傳輸二進位制,例如上傳圖片用的 FormData物件就可以用data來傳輸 data: { firstName: 'Fred' }, // timeout(常用) 設定請求的超時時間,超過了時間請求還沒有響應的會會報錯走到catch,預設值是0 表示一直等待響應 timeout: 1000, // onUploadProgress 用來監聽上傳的進度,一般圖片上傳時候的顯示進度條這裡會用上 onUploadProgress: function (progressEvent) { // Do whatever you want with the native progress event }, }
上面是很常用的設定,推薦還是全部記住,當然,我後面還會依據這些設定去做一些axios
的高階用法
axios
在返回值的時候,是會預設的對我們的這次請求進行一次包裝。
官方檔案頁給了一個很詳細的說明,我再來用我的語言翻譯一下下吧。
{ // 請求響應的返回值 data: {}, // 請求狀態 status: 200, // 狀態說明文字 statusText: 'OK', // 請求的請求頭 headers: {}, // 這次請求用到的 設定 指 剛剛問題一的設定 config: {}, // 請求範例 表示 axios 底層 封裝的 XMLHttpRequest 的資訊 request: {} }
ok
。現在我們從發起請求到響應結果的這個過程中我們都有所瞭解了。
接下來我在介紹一些經常忽略的地方和一些小技巧
我們看到上面的程式碼,因為我們發起請求,
get請求的引數一般是拼接到url上,所以我們在axios中會用 params這個設定來攜帶我們請求引數
post請求的引數一般是放在請求體裡面的,所以我們會在axios中使用data這個設定來表示我們的請求引數
在axios
api
介紹中,
針對get
,我們發現還有這樣的一個api
。 axios.get(url[, config])
我們來試一下怎麼玩,改裝一下我們的 testGet
方法
可以看出,axios.get
這個api
只是把 url
和method
這兩個設定拆出來了。
注意啊,axios.get
這裡有兩個引數,第一個是url,第二個是 我們的設定選項。
那麼問題來了,這兩種寫法有什麼區別呢?
直接翻看原始碼找找定義。
axios
包下的index.js
引入了./lib/axios
,這裡又引入了一個./core/Axios
在這個 ./core/Axios
中。我們就可以看到下面的內容。
我們可以看到,他就是在原型上繫結了 我們常用的 get post put ....
等常用方法,讓他去調this.request
方法,引數就是把我們的設定資訊給合併了,mergeConfig
看方法名就知道這個是合併Config
的一個方法,返回了最終的設定資訊物件。
在29行這裡還定義了 request
方法,大致看一下就是根據設定,做一些優化
比如方法名大小寫轉換。
比如最終給我們包裝成了一個 promise
物件返回
所以本質上,axios({})
和我們的 axios.get(url,{})
是兩個一模一樣的方法。
ok
,axios.post
axios.put
等用法,和get
類似
這兩種方法 可以說是蘿蔔白菜,各有所愛。各有各的喜好,你自己使用那種方法就看你喜歡哪種啦。
話不多說貼程式碼先,
uploadImg() { console.log(this.file); const formData = new FormData(); formData.append('file', this.file); axios({ url: 'XXXXXXXXXXXXXXXXXXXXXXXXXX', method: 'post', data: formData, onUploadProgress(progressEvent) { let complete = (((progressEvent.loaded / progressEvent.total) * 100) | 0) + '%'; console.log('上傳 ' + complete); }, }).then((res) => { console.log('uploadImg res==>', res); }); },
其中 this.file
是我們 input type
為file
選中檔案後,e.target.files
的值,當然,這個值是陣列,我們需要他的第一個
注意的就是使用 data
傳遞了一個引數,引數型別是 FromData
。
好的到這裡,我們就簡單的學習的axios
的使用,當然會有很多的小夥伴說,就這啊,這個東西不是看一眼就會的嗎?
既然看到了這裡。我肯定不會讓你白來的。加下來我們說一下高階用法。
學習高階用法之前,我們要問一下,為什麼要這樣做。我們之前那樣做有哪些問題?
我們真實的開發環境中,會有線上地址,開發地址,測試地址。這些地址我們怎麼樣能夠做到快速的切換呢?
我們發現在axios
的設定中,我們每一次都會改變的是 url
method
data
params
,很少改變的是 header
baseurl
timeout
,那麼針對很少變動的我們能不能統一的封裝一下。
每一次發請求的時候我想在控制檯上輸出一下我當前請求的資訊,能不能封裝起來,不要每一次都編寫。
axios
的返回值裡面,有太多東西是我們不需要的了,我們明明關注的只是 返回的 data
,每一次請求返回的時候我們都要 res.data
一下,很煩,這一步能不能省略呢?
請求往往會遇到一些錯誤,這些錯誤我每一次都需要在 catch
中處理,程式碼寫的又臭又長,明明只是一個 log error
的功能,可是每一次請求的地方都需要寫 catch
,這裡能不能省略呢?
ok,有了問題,我們接下來寫程式碼就會方便很多了。一個個解決,幹就完事了。
在解決上面的問題之前,我們先介紹一些axios
的高階用法,一開始,我們引入了axios
,直接使用 axios({})
,方法傳遞設定的方式發起網路請求,在axios
中進行設定的方法,一共有3總
我們可以直接在 axios.default
上進行預設設定
// 全域性預設設定 axios.defaults.baseURL = 'https://api.example.com'; axios.defaults.timeout = 1000 * 5
axios
有一個create
方法,返回的其實還是一個axios
物件,但是我們在create
中可以指定一些預設設定,返回的範例物件使用的時候就會遵循這些預設設定。
// axios範例預設設定 const request = axios.create({ baseURL: 'https://api.example.com', timeout: 1000 * 8 });
這個我們見過了,就不多說了。
// 方法設定 axios({url: '',baseURL: 'https://api.example.com', timeout: 1000 * 10})
ok,介紹了三種設定,我們說一下設定的優先順序
config
引數設定;default
中的設定;可能很多小夥伴還不懂這三個環境有什麼區別。
首先假設我們的三種環境對應的地址如下
// 生產環境 192.168.0.1:8080/ // 開發環境 192.168.0.1:8080/dev/ // 測試環境 192.168.0.1:8080/test-a/
首先,專案是前後端分離的,我們會先在測試環境下編寫程式碼,測試環境的意思是,前端和後端的程式碼都是在實時編寫的,比如我們前端對接的後端有2個人A,B,開發環境就有個一個功能發起的請求是要傳送到A的電腦上的(A後端正在開發中),地址可能就是 192.168.0.1:8080/test-a
,明天來編寫程式碼又是要和B對接,這個時候的請求是會傳送到B的電腦上,地址可能就是192.168.0.1:8080/test-b
。測試環境的意思就是程式碼實時在編寫,功能結構是聯調到別人的本地。
現在程式碼開發了一個星期,開發的差不多了,就會將程式碼提交到開發環境。這個時候介面就是對接的 192.168.0.1:8080/dev
這個地址
首先要明確,我們一直編寫程式碼屬於測試環境,提交到開發環境是程式碼的一個小版本編寫完成了,程式碼在開發環境下是沒有我們本地測試環境變動的那麼快,我們之後在編寫其他功能的時候又是對接的測試環境。
提交到開發環境之後,公司裡面的產品呀,測試人員呀,就會在開發環境上,使用你的程式碼,看看你的程式碼有沒有什麼bug
,如果有bug
,你就需要在你的測試環境去修改bug
,修改完成之後在提交到開發環境讓他們去測試,直到最終沒有bug
了,開發環境的程式碼就會被提交到生產環境,生產環境的意思是這裡的程式碼是面向使用者了,是讓哪些什麼都不懂的使用者來使用了。
有點繞口,小總結一下。
生產環境是面向使用者的
開發環境是面向測試人員的,他們來找bug的
測試環境是面向 我們這些coder的,我們在這裡編寫程式碼
當然,有一些小公司是沒有測試環境的,每一次程式碼都是後端編寫完成提交到開發環境,前端直接對接開發環境的,遇到問題了後端就去改程式碼,改完之後需要打包釋出到開發環境,這樣前端才能繼續對接,就沒有測試環境直接連線到後端開發的電腦上這麼方便。
這個baseUrl
是什麼東東,第一次見的人可能有點迷惑。舉個栗子:
新增使用者功能的介面可能是下面這樣的:
// 生產環境 192.168.0.1:8080/user/add // 開發環境 192.168.0.1:8080/dev/user/add // 測試環境 192.168.0.1:8080/test-a/user/add
我們很快就發現了,明明我們新增使用者只是關心 /user/add
這個路徑,哪怕切換了環境後面的路徑也是不會修改的,那我們每次寫程式碼能不能忽略字首呢?
當然可以,這就是 baseUrl
的作用
可以理解成,真正的請求地址 = baseUrl + url
好的,瞭解這麼多之後,我們就開始封裝我們的axios把
我們優先來改一下我們的檔案目錄結構。
在utils
中有一個 request.js
,在這裡我們封裝我們的axios
。
在api
目錄中有user.js
在這裡,我們使用我們封裝的request,管理和user
有關的介面
在需要調介面的地方我們就直接引入api
中的方法就好了。
首先在 utils/request.js
中編寫以下程式碼。
在api/user.js
中編寫一下程式碼
app.vue
中呼叫
ok,這樣依賴我們就可以解決我們之前提出的問題1和問題2了
官方檔案告訴我們,axios
的範例是有請求攔截器的,在這裡會對我們的請求做一些攔截。
我們編寫程式碼試試看這個config
是什麼東東
列印結果
就是我們的congif
啊,那我們根據這個客製化一一下
這樣我們的問題3就解決了
在請求的時候我們往往會新增token
欄位來鑑權,新增token
的方法有很多,下面我來介紹幾種常用的,只負責新增。不管有沒有新增成功,不成功後端會報錯的,之後我們在處理後端報錯的情況就好了。
api中手動新增,需要了我就新增,程式碼如下
請求傳參的時候新增一個自定義的引數,表示token
欄位需不需要。
之後在我們的請求攔截器中判斷這個欄位進行處理
在解決問題4和5之前。我先總結一下我遇到過的響應方式。
方式1:後端不解決報錯,直接丟給前端,這裡我們最直觀的感受就是返回的狀態碼是500。
方式2:後端解決報錯,每次出錯包裝一下返回給前端,這裡我們最直觀的感受是。每一次請求並不會出500錯誤都是狀態碼為200成功的請求,但是返回值會多一些東西,舉個返回值的栗子,當然,下面的code,msg
這個不同的公司有不同的規範。
{ // 我們實際請求的返回值 data:{....}, // 我們實際請求的狀態碼,後端包裝報錯的花,這個code會改變,比如500,或者每一個公司有直接的狀態碼規範 code:200, // 伺服器給我們的資訊,一般成功的話沒有資訊,出現異常了這個欄位表示錯誤原因 msg:"請求成功" }
先看一下官方檔案,如何我們寫道我們的程式碼裡面列印一下這個response
看看。
因為為根據
user
編寫的介面地址是假的,為了展示效果我就切換成https://httpbin.org/get,不過這裡的邏輯是不會變的哦,只是地址改變了
我們發現,響應攔截器就是會過一邊我們的結果,這樣我們就可以在這裡進行一些程式碼編寫。
比如問題4,我們只需要編寫成下面這樣就可以了。
現在我們來處理一下我們最棘手的問題。如何攔截錯誤?
我們先引入一下elementUI(npm i element-ui -S
),在遇到錯誤的時候我們使用message元件進行一個彈框提示。
攔截錯誤之前,需要了解我們自己公司對應的一套響應策略,針對策略我們進行不同的處理。
首先我們處理一下請求報錯的情況,比如404,500等等
首行引入import { Message } from 'element-ui';
這個error
還是要return
一下,這樣才會被我們自己些的catch
捕獲到,我們這裡只是封裝了全域性的報錯提示,有的時候針對某些請求報錯我們還需要自己catch
處理。
請求正常的情況我們也還是要處理的,因為有一下公司後端會自己攔截錯誤,返回狀態碼還是200 但是這個時候資料不對並且有錯誤資訊
這裡我們規定,所有的請求都會有
data,code,msg
欄位,請求成功code
是200,data
返回正常資料,請求失敗了code
是錯誤狀態碼,data
沒有資料,並且有~錯誤提示。(自己封裝的時候根據自己公司的後臺介面規範來寫)
ok完整的程式碼如下,首部引入的 Router
(學習視訊分享:)
以上就是axios基於es6的什麼的詳細內容,更多請關注TW511.COM其它相關文章!