一、Axios是什麼?
Axios是一個基於promise的網絡請求庫,可用於node.js和瀏覽器中。它是isomorphic的(即同一套代碼可以運行在瀏覽器和node.js中)。在服務端它使用原生node.js http模塊,而在客戶端(瀏覽器端)則使用XMLHttpRequests。
特性
1. 從瀏覽器創建XMLHttpRequests,從node.js創建http請求
2. 支持promise API
3. 攔截請求和相應,轉換請求和相應數據,取消請求,自動轉換JSON數據
4. 客戶端支持防禦XSRF
二、取消請求
Axios支持以fetch API的方式,AbortController取消請求
const controller = new AbortController(); axios.get('/foo/bar',{ signal:controller.signal }).then(res => { console.log(res.data) }) //取消請求 controller.abort()
三、攔截器
在請求或響應被then或catch處理籤攔截它們
//添加請求攔截器 axios.interceptors.request.use(config => { //在發送請求之前做些什麼 return config },err => { //對請求錯誤做些什麼 return Promise.reject(err) })
//添加響應攔截器 axios.interceptors.response.use(res=>{ //2xx範圍的狀態碼都會觸發該函數 //對響應數據做點什麼 return response },err=>{ return Promise.reject(err) })
如果你需要稍後移除攔截器,可以這樣
const myInterceptor = axios.interceptors.request.use(/*...*/) axios.interceptors.request.reject(myInterceptor);
可以給自定義的axios實例添加攔截器
const instance = axios.create(); instance.interceptors.request.use(/**/)
四、請求失敗,重複發送請求
1. 使用 axios.create 創建 axios,設置請求超時時間,重試請求次數,重試請求間隔
2. 設置響應攔截器
a。若返回響應內容,則直接返回錯誤信息,不再發送請求
b。若沒有響應內容,則記錄發送請求次數,若小於重試請求次數,返回 一個 promise,在發送下一次請求之前停留一段時間,再次重複請求,否則,返回錯誤信息
import axios from 'axios'; //創建一個axios實例 const requests = axios.create({ timeout: 5 * 1000, //請求超時時間(5秒後還未接收到數據,就需要再次發送請求) retry: 3, //設置全局重試請求次數(最多重試幾次請求) retryDelay: 1000, //設置全局請求間隔 }); //響應攔截器 requests.interceptors.response.use((res) => { return Promise.resolve(res.data); }, (error) => { //console.log(error); //超時處理 error.config是一個對象,包含上方create中設置的三個參數 var config = error.config; if (!config || !config.retry) return Promise.reject(error); //如果有響應內容,就直接返回錯誤信息,不再發送請求 if(error.response.data){ return Promise.reject({type: "error", msg: error.response.data}); } // __retryCount用來記錄當前是第幾次發送請求 config.__retryCount = config.__retryCount || 0; // 如果當前發送的請求大於等於設置好的請求次數時,不再發送請求,返回最終的錯誤信息 if (config.__retryCount >= config.retry) { if (error.message === "Network Error") { //message爲"Network Error"代表斷網了 return Promise.reject({type: "warning",msg: "網絡連接已斷開,請檢查網絡"}); } else if (error.message === "timeout of 5000ms exceeded") { //網太慢了,5秒內沒有接收到數據,這裏的5000ms對應上方timeout設置的值 return Promise.reject({type: "warning",msg: "請求超時,請檢查網絡"}); } else { //除以上兩種以外的所有錯誤,包括接口報錯 400 500 之類的 return Promise.reject({type: "error",msg: "出現錯誤,請稍後再試"}); } } // 記錄請求次數+1 config.__retryCount += 1; // 設置請求間隔 在發送下一次請求之前停留一段時間,時間爲上方設置好的請求間隔時間 var backoff = new Promise(function (resolve) { setTimeout(function () { resolve(); }, config.retryDelay || 1); }); // 再次發送請求 return backoff.then(function () { return requests(config); }); }) export default requests;
五、爲什麼支持瀏覽器中發送請求也支持node發送請求?
使用的是適配器模式
- 判斷環境,然後根據環境使用對應的適配器
- 在 axios.defaults.adapter 中,判斷在瀏覽器環境中使用 XMLHttpRequest 請求,在node環境中使用http請求