摘要:使用了攔截器處理相關(guān)問題,這樣就不再需要使用來做錯誤的處理。萬惡的攔截器一些處理無論是對成功的處理還是對失敗的處理,如果攔截器不拋出錯誤,那么終將還會執(zhí)行里面處理請求成功的函數(shù),即使你返回。
一 前言
本文適合剛接觸axios或者使用過幾次的同學(xué)來分享交流一些入門經(jīng)驗(yàn),本文同樣適用熟悉axios的同學(xué)來作為參考手冊。
默認(rèn)你已經(jīng)看過axios的相關(guān)文檔:axios文檔 GitHub,通過文檔了解基礎(chǔ)的使用之后,接下來你可以進(jìn)入正文。
axios = Ajax + 異步處理
1.axios的get與post方法傳入?yún)?shù)的區(qū)別(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是放在參數(shù)對象的params屬性里面,post是直接放在參數(shù)對象里面。
2.學(xué)會使用axios.create( )創(chuàng)建axios實(shí)例var instance = axios.create({ baseURL: "https://some-domain.com/api/", timeout: 1000, headers: {"X-Custom-Header": "foobar"} });
創(chuàng)建實(shí)例的好處:統(tǒng)一(批量)處理request/response
(1)例如你在每次的請求中都要帶 cookie, 你或許可以在每個請求中這么寫:
axios.get("/user1",{withCredentials:true}); axios.get("/user2",{withCredentials:true}); ... ...
但是你也可以這么用:
var instance = axios.create({ withCredentials:true }); instance.get("/user1").then(); instance.get("/user2").then(); ... ...
(2)如果你的多個請求前綴都是相同的,那么你就可以使用baseUrl
bad:
axios.get("http://www.baidu.com/api/city").then(); axios.get("http://www.baidu.com/api/region").then(); axios.get("http://www.baidu.com/api/user").then();
good:
var instance = axios.create({ baseUrl: http://www.baidu.com/api }); instance.get("/city").then(); instance.get("/region").then(); instance.get("/user").then();
(3)其他方法推薦
設(shè)置超時時間:timeout
設(shè)置報文頭:header
等等
(1)使用與取消
我們可以這么用:
// 添加請求攔截器 axios.interceptors.request.use(function (config) { // 在發(fā)送請求之前做些什么 return config; }, function (error) { // 對請求錯誤做些什么 return Promise.reject(error); }); // 添加響應(yīng)攔截器 axios.interceptors.response.use(function (response) { // 對響應(yīng)數(shù)據(jù)做點(diǎn)什么 return response; }, function (error) { // 對響應(yīng)錯誤做點(diǎn)什么 return Promise.reject(error); });
建議將攔截器掛在到實(shí)例上:
var instance = axios.create(); instance.interceptors.request.use(function () {/*...*/});
如果你想在稍后移除攔截器,可以這樣:
var myInterceptor = axios.interceptors.request.use(function () {/*...*/}); axios.interceptors.request.eject(myInterceptor);
(2)注意事項(xiàng)
攔截器可以攔截請求和攔截響應(yīng),在請求或響應(yīng)被 then 或 catch 處理前攔截它們。
它接受兩個函數(shù)類型的參數(shù),一個是成功請求/返回的函數(shù),一個是失敗請求/返回的函數(shù);可以在這些函數(shù)里面做一些事情,例如對于401未授權(quán)的錯誤,我們可以重定向到登陸頁:
instance.interceptors.response.use(function (res) { return res; },function(error){ if (error.response.status === 401) { login(); return; } });
需要記住的是一旦你返回成功,如果沒什么事可做,其他的事交給then之后來做,記得返回response/request,不然then接受不到響應(yīng)。
(3)使用了攔截器處理相關(guān)問題,這樣就不再需要使用catch來做錯誤的處理。
4.萬惡的攔截器instance.interceptors.response.use(function (res) { return res; },function(error){ if (error.response.status === 401) { /*一些處理*/ throw error; } });
無論是對成功的處理還是對失敗的處理,如果攔截器不拋出錯誤throw error,那么終將還會執(zhí)行then里面處理請求成功的函數(shù),即使你返回undefined。
所以,建議在錯誤處理的最后拋出錯誤!
轉(zhuǎn)載文章鏈接:https://juejin.im/post/5a293e...
//引入axios import axios from "axios" let cancel ,promiseArr = {} const CancelToken = axios.CancelToken; //請求攔截器 axios.interceptors.request.use(config => { //發(fā)起請求時,取消掉當(dāng)前正在進(jìn)行的相同請求 if (promiseArr[config.url]) { promiseArr[config.url]("操作取消") promiseArr[config.url] = cancel } else { promiseArr[config.url] = cancel } return config }, error => { return Promise.reject(error) }) //響應(yīng)攔截器即異常處理 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 = "未授權(quán),請重新登錄" 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 = "服務(wù)器端出錯" break; case 501: error.message = "網(wǎng)絡(luò)未實(shí)現(xiàn)" break; case 502: error.message = "網(wǎng)絡(luò)錯誤" break; case 503: error.message = "服務(wù)不可用" break; case 504: error.message = "網(wǎng)絡(luò)超時" break; case 505: error.message = "http版本不支持該請求" break; default: error.message = `連接錯誤${error.response.status}` } } else { error.message = "連接到服務(wù)器失敗" } Message.error(error);//Message 一個UI提示組件 return Promise.resolve(error.response) }) axios.defaults.baseURL = "/api" //設(shè)置默認(rèn)請求頭 axios.defaults.headers = { "X-Requested-With": "XMLHttpRequest" } axios.defaults.timeout = 10000 export 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) }) }) } }
注意:這段代碼中沒有創(chuàng)建axios實(shí)例,個人覺得創(chuàng)建實(shí)例會更方便調(diào)用。
根據(jù)官方文檔,如何取消一個尚未得到響應(yīng)的請求:
var CancelToken = axios.CancelToken; var cancel; axios.get("/user/12345", { cancelToken: new CancelToken(function executor(c) { // An executor function receives a cancel function as a parameter cancel = c; }) }); // cancel the request cancel();6.axios 失敗重新請求的封裝
//在main.js設(shè)置全局的請求次數(shù),請求的間隙 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, reject if (!config || !config.retry) return Promise.reject(err); // Set the variable for keeping track of the retry count config.__retryCount = config.__retryCount || 0; // Check if we"ve maxed out the total number of retries if (config.__retryCount >= config.retry) { // Reject with the error return Promise.reject(err); } // Increase the retry count config.__retryCount += 1; // Create new promise to handle exponential backoff var backoff = new Promise(function (resolve) { setTimeout(function () { resolve(); }, config.retryDelay || 1); }); // Return the promise in which recalls axios to retry the request return backoff.then(function () { return axios(config); }); });7.更實(shí)用的封裝
通常不需要請求失敗之后再重新請求
請求失敗之后不需要把錯誤提示的那么詳細(xì)
通常在請求時還伴隨加載狀態(tài)【重要】
示例代碼:
// 創(chuàng)建axios實(shí)例 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:"網(wǎng)絡(luò)連接錯誤", } // 提示“網(wǎng)絡(luò)連接錯誤” return Promise.resolve(response); } }); export default axiosInstance;
和上面的參考封裝有以下不同之處:
攔截器里只拋出網(wǎng)絡(luò)連接失敗的錯誤
無論服務(wù)器返回的請求是成功(200)還是失敗(404 500等),都會被resolve,這就會有三點(diǎn)影響:
業(yè)務(wù)邏輯上.then(()=>{})的時候都會走resolve的函數(shù),這樣就可以在這個函數(shù)里控制loading狀態(tài)
resolve的函數(shù)需要根據(jù)后端response的成功標(biāo)示來判斷請求是成功還是失敗
這樣就不再需要.catch()
三 后記簡單的介紹了一些常見事項(xiàng)和基礎(chǔ)用法,有更多的內(nèi)容等待大家去探索,歡迎留言交流~~
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/90468.html
摘要:說起,其實(shí)早在出現(xiàn)之前,網(wǎng)頁就是在服務(wù)端渲染的。沒有涉及流式渲染組件緩存對的服務(wù)端渲染有更深一步的認(rèn)識,實(shí)際在生產(chǎn)環(huán)境中的應(yīng)用可能還需要考慮很多因素。選擇的服務(wù)端渲染方案,是情理之中的選擇,不是對新技術(shù)的盲目追捧,而是一切為了需要。 作者:威威(滬江前端開發(fā)工程師)本文原創(chuàng),轉(zhuǎn)載請注明作者及出處。 背景 最近, 產(chǎn)品同學(xué)一如往常笑嘻嘻的遞來需求文檔, 縱使內(nèi)心萬般拒絕, 身體倒是很誠實(shí)...
平日學(xué)習(xí)接觸過的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個網(wǎng)址:http://www.kancloud.cn/jsfron... 1. Javascript 前端生成好看的二維碼 十大經(jīng)典排序算法(帶動圖演示) 為什么知乎前端圈普遍認(rèn)為H5游戲和H5展示的JSer 個人整理和封裝的YU.js庫|中文詳細(xì)注釋|供新手學(xué)習(xí)使用 擴(kuò)展JavaScript語法記錄 - 掉坑初期工具 漢字拼音轉(zhuǎn)換...
平日學(xué)習(xí)接觸過的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個網(wǎng)址:http://www.kancloud.cn/jsfron... 1. Javascript 前端生成好看的二維碼 十大經(jīng)典排序算法(帶動圖演示) 為什么知乎前端圈普遍認(rèn)為H5游戲和H5展示的JSer 個人整理和封裝的YU.js庫|中文詳細(xì)注釋|供新手學(xué)習(xí)使用 擴(kuò)展JavaScript語法記錄 - 掉坑初期工具 漢字拼音轉(zhuǎn)換...
平日學(xué)習(xí)接觸過的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個網(wǎng)址:http://www.kancloud.cn/jsfron... 1. Javascript 前端生成好看的二維碼 十大經(jīng)典排序算法(帶動圖演示) 為什么知乎前端圈普遍認(rèn)為H5游戲和H5展示的JSer 個人整理和封裝的YU.js庫|中文詳細(xì)注釋|供新手學(xué)習(xí)使用 擴(kuò)展JavaScript語法記錄 - 掉坑初期工具 漢字拼音轉(zhuǎn)換...
平日學(xué)習(xí)接觸過的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個網(wǎng)址:http://www.kancloud.cn/jsfron... 1. Javascript 前端生成好看的二維碼 十大經(jīng)典排序算法(帶動圖演示) 為什么知乎前端圈普遍認(rèn)為H5游戲和H5展示的JSer 個人整理和封裝的YU.js庫|中文詳細(xì)注釋|供新手學(xué)習(xí)使用 擴(kuò)展JavaScript語法記錄 - 掉坑初期工具 漢字拼音轉(zhuǎn)換...
閱讀 2248·2021-11-18 10:02
閱讀 3499·2021-11-15 11:36
閱讀 1124·2019-08-30 14:03
閱讀 741·2019-08-30 11:08
閱讀 2772·2019-08-29 13:20
閱讀 3295·2019-08-29 12:34
閱讀 1382·2019-08-28 18:30
閱讀 1648·2019-08-26 13:34