axios基於es6的什麼

2022-08-30 22:03:44

axios基於es6的promise機制。Axios是一個基於promise的HTTP庫,類似於jQuery的ajax,用於http請求。Axios支援Promise API,在瀏覽器中傳送XMLHttpRequests請求,在node.js中傳送http請求;也可以攔截請求與響應,或轉換請求資料和響應資料。

如何快速入門VUE3.0:進入學習

本教學操作環境:windows7系統、ECMAScript 6版、Dell G3電腦。

axios基本介紹

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

所以整個專案的環境看起來就是這樣

1.png

當然,並不是說axios不能夠在非 vue 的環境下使用,這裡我只是為了寫程式碼方便,普通的,使用瀏覽器 script 標籤 引入 axios ,在window物件上就會有一個 axios物件,這樣你在瀏覽器環境使用和我在vue中使用起來就是完全一致的了。

看起來就像這樣:

  • 引入

2.png

  • 效果

3.png

請求地址

httpbin.org/

這個網址學習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 方法吧。

4.png

app.vue中,我們引入axios,並且使用axios攜帶引數傳送了一個get請求。

我們先來看一下瀏覽器的網路請求

5.png

可以看到,我們發出的請求是成功了的。我們現在再來看一下我們 then中列印出來的響應結果。

6.png

我們發現then中,列印出來的東西好像比我們網路請求的返回值內容要多。但是data這個對應的值就是我們請求返回的結果。

ok。到現在,我們是可以使用axios傳送網路請求了。但是現在我們還是有很多的疑問。

  • axios({}) 這個方法能發出一個網路請求,但是方法傳入的物件是什麼意思呢?

  • then 列印出來的 res 返回值中,為什麼會多了很多其他的引數?

axios的設定

7.png

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在返回值的時候,是會預設的對我們的這次請求進行一次包裝。

8.png

官方檔案頁給了一個很詳細的說明,我再來用我的語言翻譯一下下吧。

{
  // 請求響應的返回值
  data: {},
  // 請求狀態
  status: 200,
  // 狀態說明文字
  statusText: 'OK',
  // 請求的請求頭
  headers: {},
  // 這次請求用到的 設定  指 剛剛問題一的設定
  config: {},
  // 請求範例  表示 axios 底層 封裝的 XMLHttpRequest 的資訊
  request: {}
}

ok。現在我們從發起請求到響應結果的這個過程中我們都有所瞭解了。

接下來我在介紹一些經常忽略的地方和一些小技巧

小誤區

9.png

我們看到上面的程式碼,因為我們發起請求,

  • get請求的引數一般是拼接到url上,所以我們在axios中會用 params這個設定來攜帶我們請求引數

  • post請求的引數一般是放在請求體裡面的,所以我們會在axios中使用data這個設定來表示我們的請求引數

小技巧

axios api介紹中,

針對get,我們發現還有這樣的一個apiaxios.get(url[, config])

我們來試一下怎麼玩,改裝一下我們的 testGet方法

10.png

可以看出,axios.get 這個api只是把 urlmethod這兩個設定拆出來了。

注意啊,axios.get 這裡有兩個引數,第一個是url,第二個是 我們的設定選項。

注意

那麼問題來了,這兩種寫法有什麼區別呢?

直接翻看原始碼找找定義。

axios包下的index.js引入了./lib/axios,這裡又引入了一個./core/Axios

在這個 ./core/Axios中。我們就可以看到下面的內容。

11.png

我們可以看到,他就是在原型上繫結了 我們常用的 get post put .... 等常用方法,讓他去調this.request方法,引數就是把我們的設定資訊給合併了,mergeConfig看方法名就知道這個是合併Config的一個方法,返回了最終的設定資訊物件。

12.png

在29行這裡還定義了 request方法,大致看一下就是根據設定,做一些優化

比如方法名大小寫轉換。

13.png

比如最終給我們包裝成了一個 promise物件返回

所以本質上,axios({}) 和我們的 axios.get(url,{})是兩個一模一樣的方法。

okaxios.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 typefile 選中檔案後,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({}),方法傳遞設定的方式發起網路請求,在axios中進行設定的方法,一共有3總

全域性預設設定

我們可以直接在 axios.default上進行預設設定

// 全域性預設設定
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.timeout = 1000 * 5

axios範例設定

axios有一個create方法,返回的其實還是一個axios物件,但是我們在create中可以指定一些預設設定,返回的範例物件使用的時候就會遵循這些預設設定。

// axios範例預設設定
const request = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 1000 * 8
});

axios方法設定

這個我們見過了,就不多說了。

// 方法設定
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

這個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把

封裝axios預設設定

我們優先來改一下我們的檔案目錄結構。

14.png

utils中有一個 request.js,在這裡我們封裝我們的axios

api目錄中有user.js 在這裡,我們使用我們封裝的request,管理和user有關的介面

在需要調介面的地方我們就直接引入api中的方法就好了。

首先在 utils/request.js中編寫以下程式碼。

15.png

api/user.js中編寫一下程式碼

16.png

app.vue中呼叫

17.png

ok,這樣依賴我們就可以解決我們之前提出的問題1問題2

請求攔截器

18.png

官方檔案告訴我們,axios的範例是有請求攔截器的,在這裡會對我們的請求做一些攔截。

我們編寫程式碼試試看這個config是什麼東東

19.png

列印結果

20.png

就是我們的congif啊,那我們根據這個客製化一一下

21.png

這樣我們的問題3就解決了

新增token請求頭

在請求的時候我們往往會新增token欄位來鑑權,新增token的方法有很多,下面我來介紹幾種常用的,只負責新增。不管有沒有新增成功,不成功後端會報錯的,之後我們在處理後端報錯的情況就好了。

  • api中手動新增,需要了我就新增,程式碼如下

22.png

  • 請求傳參的時候新增一個自定義的引數,表示token欄位需不需要。

23.png

之後在我們的請求攔截器中判斷這個欄位進行處理

24.png

響應方式

在解決問題4和5之前。我先總結一下我遇到過的響應方式。

方式1:後端不解決報錯,直接丟給前端,這裡我們最直觀的感受就是返回的狀態碼是500。

方式2:後端解決報錯,每次出錯包裝一下返回給前端,這裡我們最直觀的感受是。每一次請求並不會出500錯誤都是狀態碼為200成功的請求,但是返回值會多一些東西,舉個返回值的栗子,當然,下面的code,msg這個不同的公司有不同的規範。

{
    // 我們實際請求的返回值
  	data:{....},
    // 我們實際請求的狀態碼,後端包裝報錯的花,這個code會改變,比如500,或者每一個公司有直接的狀態碼規範
    code:200,
    // 伺服器給我們的資訊,一般成功的話沒有資訊,出現異常了這個欄位表示錯誤原因
    msg:"請求成功"
}

響應攔截器

25.png

先看一下官方檔案,如何我們寫道我們的程式碼裡面列印一下這個response看看。

因為為根據user編寫的介面地址是假的,為了展示效果我就切換成https://httpbin.org/get,不過這裡的邏輯是不會變的哦,只是地址改變了

26.png

27.png

我們發現,響應攔截器就是會過一邊我們的結果,這樣我們就可以在這裡進行一些程式碼編寫。

比如問題4,我們只需要編寫成下面這樣就可以了。

28.png

現在我們來處理一下我們最棘手的問題。如何攔截錯誤?

我們先引入一下elementUI(npm i element-ui -S),在遇到錯誤的時候我們使用message元件進行一個彈框提示。

攔截錯誤之前,需要了解我們自己公司對應的一套響應策略,針對策略我們進行不同的處理。

首先我們處理一下請求報錯的情況,比如404,500等等

首行引入import { Message } from 'element-ui';

29.png

這個error還是要return一下,這樣才會被我們自己些的catch捕獲到,我們這裡只是封裝了全域性的報錯提示,有的時候針對某些請求報錯我們還需要自己catch處理。

請求正常的情況我們也還是要處理的,因為有一下公司後端會自己攔截錯誤,返回狀態碼還是200 但是這個時候資料不對並且有錯誤資訊

這裡我們規定,所有的請求都會有 data,code,msg欄位,請求成功code是200,data返回正常資料,請求失敗了code是錯誤狀態碼,data沒有資料,並且有~錯誤提示。(自己封裝的時候根據自己公司的後臺介面規範來寫)

ok完整的程式碼如下,首部引入的 Router

30.png

(學習視訊分享:)

以上就是axios基於es6的什麼的詳細內容,更多請關注TW511.COM其它相關文章!