Axios 面試題

一、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發送請求?

使用的是適配器模式

  1. 判斷環境,然後根據環境使用對應的適配器
  2. 在 axios.defaults.adapter 中,判斷在瀏覽器環境中使用 XMLHttpRequest 請求,在node環境中使用http請求

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章