關於 axios 是什麼?以及怎麼用?

2023-07-05 06:01:23

〇、前言

Axios 是一個基於 promise 的 HTTP 庫,可以用在瀏覽器和 Node.js 中。簡單的講就是可以傳送 Get、Post 請求。

諸如 Vue、React、Angular 等前端框架都可以使用 Axios,由於他們不操作 DOM,所以就不必須參照 jQuery。如果你的專案裡面用了 jQuery,此時就不需要多此一舉了,jQuery 裡面本身就可以傳送請求($.get(URL,data,function(data,status,xhr),dataType))。

幾個易混淆的概念

  1. Ajax:Asynchronous JavaScript And XML,翻譯過來就是「非同步的 Javascript 和 XML」,屬於一個術語或概念模型,並不特指某一技術,它很重要的特性之一就是讓頁面實現區域性重新整理,而無需過載整個頁面
  2. XHR:XMLHttpRequest 物件用於與伺服器互動。通過 XMLHttpRequest 可以在不重新整理頁面的情況下請求特定 URL,取的資料後重新整理區域性頁面。因此,XHR 可以實現 Ajax 請求
  3. Promise:是 ES6 新增的一個物件,是對 XHR 的一種封裝
    它就像一個容器,裡面存放著未來才會執行的函數名,處理結果要在非同步操作完成後拿到,然後通過 .then() 進行後續操作。
    它有三種狀態:Pending(進行中)、Fulfilled(成功)、Rejected(拒絕),進入成功或拒絕的狀態就不會再發生改變。
  4. Fetch:是在 ES6 出現的,它使用了 ES6 提出的 Promise 物件。是一種網路請求標準 API。
  5. Axios:用於網路請求的第三方庫,參照後即可用。
    使用環境有兩種,一種是在瀏覽器端傳送 XHR 請求(中間有一層 Promise 封裝),另一種是在 nodejs 中傳送 http 請求,因此利於平臺切換。
    支援 Promise API,使用 Promise 管理非同步,告別傳統 Callback 方式;豐富的設定項,支援攔截器等高階設定。

注:一兩句話不可能講清楚他們的區別,待後續再慢慢一一展開介紹吧,如有不準確的描述,請評論區指正。

參考:你知道Ajax、Fetch、Axios三者的區別嗎?    ajax、Promise、axios總結

一、如何參照?

1、前端專案

// 1、安裝 Axios 庫
// 在專案檔案根目錄下開啟命令列,輸入如下語句
> npm install axios

// 2、js 檔案中引入
import axios from 'axios';

// 3、直接通過關鍵字 axios 傳送 http 請求
// Get 請求
axios({
  method: 'get',
  url: 'URL文字'
}).then(({data}) => {
  // 。。。
}).catch((err) =>{
    console.log("catch-err:",err);
}).finally(() =>{
  // 。。。
})

// Post 請求
axios({
  headers:{'content-type':'application/json'},
  method: 'post',
  url: 'URL文字',
  data:JSON.stringify({"dataid":dataid})
}).then(({data}) => {
  console.log("then-data:",data);
}).catch((err) =>{
    console.log("catch-err:",err);
}).finally(() =>{
  // 。。。
})

2、ASP.NET Core MVC 專案

@* 1、參照 js 包的 CDN *@
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

@* 2、通過關鍵字 axios 傳送 http 請求 *@
<script>
    // 呼叫方法 message() 檢視測試結果
    window.onload = function () {
        // Get 請求
        axios.get('https://localhost:44360/api/Methodname', {
            params: {
                mingcheng: '網路科技'
            },
            headers: {
                    'token': '1111',
            }
        }
        ).then(ret => {
            console.log("get:", ret);
        })
        // Post 請求
        axios.post('https://localhost:44360/api/Methodname',
            {
                "id": "df332b50-4abf-4fe6-814b-6d330a9ecc73",
                "gongsix": "線下"
            },
            {
                headers: {
                    'token': '1111',
                }
            }
        ).then(ret => {
            console.log("post:", ret);
        })
    }
</script>

另外,除了通過 CDN 參照 js 庫外,還可以直接新增 js 檔案到專案的靜態資料夾 wwwroot,然後在 .cshtml 頁面檔案中用過路徑參照。

簡要的三個步驟如下:

  1. 下載 js 庫檔案。可以直接在網路上下載,也可以通過通過專案的「管理 NuGet 程式包」來安裝 axios。安裝成功後,找到對應的包右鍵開啟「在檔案資源管理器中開啟資料夾」,按照路徑「Content/Scripts/axios.min.js」找到下載的最新檔案。
  2. 然後複製到「wwwroot/js/...」資料夾下備用。如下圖:

    

  3. 然後通過路徑參照後,即可在 js 指令碼中使用 axios。

@* 注意路徑代表 wwwroot 資料夾中,要對應得上 *@
<script src="~/js/axios/axios.min.js"></script>

二、語法

引數名 範例值 解釋
url '/user' 用於請求的伺服器 URL
method 'get' 建立請求時使用的方法,預設 get
baseURL 'https://some-domain.com/api/' 將自動加在 `url` 前面,除非 `url` 是一個絕對 URL(URL 必須帶有資源的完整資訊,包含協定、主機、路徑等部分)
headers {'X-Requested-With': 'XMLHttpRequest'} 自定義請求頭
params { ID: 12345 } URL 引數,會自動拼接到 URL 中
data { firstName: 'Fred' } 作為請求主體被傳送的資料,適用於'PUT'、'POST'、'PATCH' 三個請求方法。在沒有設定 transformRequest 時,必須是以下型別之一:string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams、瀏覽器專屬:FormData, File, Blob、Nodejs專屬:Stream
timeout 1000 請求超時的毫秒數(0 表示無超時時間),若超時請求將被中斷
withCredentials false 跨域請求時是否需要使用憑證,預設 false
responseType 'json' 伺服器響應的資料型別,可以是 'arraybuffer', 'blob', 'document', 'json'-預設, 'text', 'stream'
responseEncoding 'utf8' 資料編碼型別,預設 utf8
maxContentLength 2000 允許的響應內容的最大長度,設定為無限長度:Infinity

1、Get 請求

以下列舉三種寫法:

// (呼叫型1)查詢給定 ID 的 user 物件請求
axios.get('/user?ID=12345')
.then(function (response) {
    console.log(response);
})
.catch(function (error) {
    console.log(error);
});

// (呼叫型2)另一種寫法
axios.get('/user', {
    params: {
        ID: 12345
    }
})
.then(function (response) {
    console.log(response);
})
.catch(function (error) {
    console.log(error);
});

// (方法型)寫法
axios({
  method:'get',
  url:'/data.json',
  params:{
    id:'12345'
  }
}).then((res)=>{
     console.log(res)
})

 2、Post 請求

 一般上傳的資料分兩種:form-data 表單提交(圖片上傳、檔案上傳)、application/json。

// 先定義一個入參 data
let data = { id : 12 }

// (呼叫型)寫法
axios.post('/post',data)
}).then((res)=>{
     console.log(res)
})

// (方法型)寫法
axios({
  method:'post',
  url:'/post',
  data:data
}).then((res)=>{
     console.log(res)
})

關於 Post 請求的 Content-Type:

當我們直接把入參填入 json 物件,丟給後端介面,此時 Content-Type 就自動為:application/json;charset=UTF-8。

當我們把 json 物件轉為 FormData 型別,如下:

let data = { id : 12 }
let formData = new FormData()
for(let key in data){
    formData.append(key,data[key])
}

再將 formData 傳送到後端,此時Content-Type 就自動變成:multipart/form-data; boundary=...... 。

3、判斷多個請求全部完成 axios.all(sendAry).then()

// 請求列表,包含多個或多型別請求
let sendAry = [
    axios.get('URL1'),
    axios.get('URL2'),
    axios.post('URL3')
];
// 列表中的請求都完成後,才進行後續操作(可以基於ALL實現)
axios.all(sendAry).then(result => {
    console.log(result); // 輸出是一個陣列,分別儲存每一個請求的結果
    let [resA, resB, resC] = result;
});

4、攔截器

在請求或響應被 then 或 catch 處理前攔截它們。

請求攔截器

axios.interceptors.request.use(
    config=>{
        // 在傳送請求前做的操作
        return config
  },
    err=>{
        // 在請求錯誤的時候做的操作(此處錯誤,請求沒有到後端)
        return Promise.reject(err) // 這裡返回一個 promise 物件
  }
)

響應攔截器

axios.interceptors.response.use(
	res=>{
		// 請求成功對響應資料進行處理
		return res
	},err=>{
		// 響應錯誤做的操作(此處錯誤,到達後端後返回)
		return Promise.reject(err)
	}
)

下面的程式碼是我們平時傳送 Get 請求的標準形態,then 會執行請求成功後的操作,catch 用來捕獲錯誤。我們前面攔截響應後,無論是請求還是響應的攔截器,他們的 err 返回的 promise 都會進入 catch 中

axios.get().then().catch(err=>{})

取消攔截器

let inerceptors = axios.interceptors.request.use
(config=>{
     config.header = {
         auth:true
     }
     return config
})
// 如下:用 axios 全域性去呼叫 interceptors,這樣就取消攔截了
axios.inerceptors.request.eject(interceptors) 

範例:通過攔截器控制登陸狀態

// 登入狀態,有 token,後端通過 headers 中的 token 進行身份校驗
let request = axios.create({})
request.interceptors.request.use
(config => {
   config.headers.token = '' // 傳送請求前,統一將 token 加入到請求 headers
   return config
})
// 非登陸狀態,無 token
let request2 = axios.create({})

5、引數設定方法

全域性設定

// 兩個範例:(格式類同)
axios.defaults.timeout = 1000 // 全域性設定請求時長(單位:毫秒)
axios.defaults.baseURL = 'https://api.example.com'; // 統一設定請求基礎 URL

範例設定

// 在建立範例時設定預設設定
const instance = axios.create({
  baseURL: 'https://api.example.com'
});

// 建立範例後可更改預設值
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;

優先順序:請求設定 > 範例設定 > 全域性設定

6、錯誤處理

// 首先設定兩種攔截器
axios.interceptors.request.use(
	config =>{
		return config
	},
	err =>{
	return Promise.reject(err)
	}
)
axios.interceptors.response.use(
	res =>{
		return res
	},
	err =>{
		return Promise.reject(err)
	}
)

// 錯誤的獲取
axios.get('/data.json').then(res=>{
	console.log(res)
})
.catch(err =>{
	console.log(err) // 所有錯誤處理都會進入此處
})

具體的實踐過程中,我們需要建立一個統一的錯誤處理,將所有的錯誤型別都放在攔截其中,方便我們後面呼叫介面時使用

一個範例:

// 建立一個請求範例
let instance = axios.create({})
// 為請求範例新增請求攔截器
instance.interceptors.request.use(
	config =>{
		return config
	},
	err =>{
		// 請求錯誤,一般 http 狀態碼以 4 開頭,常見:401 超時,404 not found 多為前端瀏覽器錯誤
		return Promise.reject(err)
	}
)
instance.interceptors.response.use(
	res=>{
		return res
	},
	err =>{
		// 響應錯誤,一般 http 狀態碼以 5 開頭,500 系統錯誤,502 系統重啟等,偏向於伺服器端返回的報錯
        return Promise.reject(err)
  }
)

// 使用
instance.get('/data').then(res=>{
	console.log(res)
})
.catch(err => {
	console.log(err)
})

參考:完整過一遍axios,再也不怕寫請求   axios中文檔案|官方