axios入门实践
axios入門實踐
javascriptasyncaxios
更新于 2019-02-21???約 19 分鐘
一 前言
本文適合剛接觸axios或者使用過幾次的同學來分享交流一些入門經驗,本文同樣適用熟悉axios的同學來作為參考手冊。
默認你已經看過axios的相關文檔:axios文檔?GitHub,通過文檔了解基礎的使用之后,接下來你可以進入正文。
二 正文
axios = Ajax + 異步處理
1.axios的get與post方法傳入參數的區別
(1)get
axios.get('/user', {params: {ID: 12345}}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});(2)post
axios.post('/user', {firstName: 'Fred',lastName: 'Flintstone'}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});get是放在參數對象的params屬性里面,post是直接放在參數對象里面。
2.學會使用axios.create( )創建axios實例
var instance = axios.create({baseURL: 'https://some-domain.com/api/',timeout: 1000,headers: {'X-Custom-Header': 'foobar'} });創建實例的好處:統一(批量)處理request/response
(1)例如你在每次的請求中都要帶 cookie, 你或許可以在每個請求中這么寫:
但是你也可以這么用:
var instance = axios.create({withCredentials:true});instance.get('/user1').then();instance.get('/user2').then();... ...(2)如果你的多個請求前綴都是相同的,那么你就可以使用baseUrl
bad:
good:
var instance = axios.create({baseUrl: http://www.baidu.com/api}); instance.get('/city').then(); instance.get('/region').then(); instance.get('/user').then();(3)其他方法推薦
設置超時時間:timeout
設置報文頭:header
等等
3.功能強大的攔截器:在請求或響應被 then 或 catch 處理前攔截它們
(1)使用與取消
我們可以這么用:
建議將攔截器掛在到實例上:
var instance = axios.create(); instance.interceptors.request.use(function () {/*...*/});如果你想在稍后移除攔截器,可以這樣:
var myInterceptor = axios.interceptors.request.use(function () {/*...*/}); axios.interceptors.request.eject(myInterceptor);(2)注意事項
攔截器可以攔截請求和攔截響應,在請求或響應被 then 或 catch 處理前攔截它們。
它接受兩個函數類型的參數,一個是成功請求/返回的函數,一個是失敗請求/返回的函數;可以在這些函數里面做一些事情,例如對于401未授權的錯誤,我們可以重定向到登陸頁:
需要記住的是一旦你返回成功,如果沒什么事可做,其他的事交給then之后來做,記得返回response/request,不然then接受不到響應。
(3)使用了攔截器處理相關問題,這樣就不再需要使用catch來做錯誤的處理。
4.萬惡的攔截器
instance.interceptors.response.use(function (res) {return res; },function(error){if (error.response.status === 401) {/*一些處理*/throw error;} });無論是對成功的處理還是對失敗的處理,如果攔截器不拋出錯誤throw error,那么終將還會執行then里面處理請求成功的函數,即使你返回undefined。
所以,建議在錯誤處理的最后拋出錯誤!
5.可供參考的二次封裝
轉載文章鏈接:https://juejin.im/post/5a293e...
//引入axios import axios from 'axios'let cancel ,promiseArr = {} const CancelToken = axios.CancelToken; //請求攔截器 axios.interceptors.request.use(config => {//發起請求時,取消掉當前正在進行的相同請求if (promiseArr[config.url]) {promiseArr[config.url]('操作取消')promiseArr[config.url] = cancel} else {promiseArr[config.url] = cancel}return config }, error => {return Promise.reject(error) })//響應攔截器即異常處理 axios.interceptors.response.use(response => {return response }, error => {if (error && error.response) {switch (error.response.status) {case 400:error.message = '錯誤請求'break;case 401:error.message = '未授權,請重新登錄'break;case 403:error.message = '拒絕訪問'break;case 404:error.message = '請求錯誤,未找到該資源'break;case 405:error.message = '請求方法未允許'break;case 408:error.message = '請求超時'break;case 500:error.message = '服務器端出錯'break;case 501:error.message = '網絡未實現'break;case 502:error.message = '網絡錯誤'break;case 503:error.message = '服務不可用'break;case 504:error.message = '網絡超時'break;case 505:error.message = 'http版本不支持該請求'break;default:error.message = `連接錯誤${error.response.status}`}} else {error.message = "連接到服務器失敗"}Message.error(error);//Message 一個UI提示組件return Promise.resolve(error.response) })axios.defaults.baseURL = '/api' //設置默認請求頭 axios.defaults.headers = {'X-Requested-With': 'XMLHttpRequest' } axios.defaults.timeout = 10000export default {//get請求get (url,param) {return new Promise((resolve,reject) => {axios({method: 'get',url,params: param,cancelToken: new CancelToken(c => {cancel = c})}).then(res => {resolve(res)})})},//post請求post (url,param) {return new Promise((resolve,reject) => {axios({method: 'post',url,data: param,cancelToken: new CancelToken(c => {cancel = c})}).then(res => {resolve(res)})})}}注意:這段代碼中沒有創建axios實例,個人覺得創建實例會更方便調用。
根據官方文檔,如何取消一個尚未得到響應的請求:
6.axios 失敗重新請求的封裝
//在main.js設置全局的請求次數,請求的間隙 axios.defaults.retry = 4; axios.defaults.retryDelay = 1000;axios.interceptors.response.use(undefined, function axiosRetryInterceptor(err) {var config = err.config;// If config does not exist or the retry option is not set, rejectif (!config || !config.retry) return Promise.reject(err);// Set the variable for keeping track of the retry countconfig.__retryCount = config.__retryCount || 0;// Check if we've maxed out the total number of retriesif (config.__retryCount >= config.retry) {// Reject with the errorreturn Promise.reject(err);}// Increase the retry countconfig.__retryCount += 1;// Create new promise to handle exponential backoffvar backoff = new Promise(function (resolve) {setTimeout(function () {resolve();}, config.retryDelay || 1);});// Return the promise in which recalls axios to retry the requestreturn backoff.then(function () {return axios(config);}); });7.更實用的封裝
示例代碼:
// 創建axios實例 const axiosInstance = axios.create({// timeout: 3000,// baseURL,withCredentials: true, });// request攔截器axiosInstance.interceptors.request.use((config) => config, (error) => Promise.reject(error));axiosInstance.interceptors.response.use((response:AxiosResponse)=> {const {data} = response || {data:{}};return Promise.resolve(data); }, (error:any) => {if(error&&error.response){ // 提示具體接口報錯return Promise.resolve(error.response);}else{const response = {code:1, // 表示錯誤的code碼message:'網絡連接錯誤',}// 提示“網絡連接錯誤”return Promise.resolve(response);} });export default axiosInstance;和上面的參考封裝有以下不同之處:
- 攔截器里只拋出網絡連接失敗的錯誤
-
無論服務器返回的請求是成功(200)還是失敗(404 500等),都會被resolve,這就會有三點影響:
- 業務邏輯上.then(()=>{})的時候都會走resolve的函數,這樣就可以在這個函數里控制loading狀態
- resolve的函數需要根據后端response的成功標示來判斷請求是成功還是失敗
- 這樣就不再需要.catch()
三 后記
簡單的介紹了一些常見事項和基礎用法,有更多的內容等待大家去探索,歡迎留言交流~~
總結
- 上一篇: 使用Avue的方法
- 下一篇: Typescript中使用Axios