精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

手寫Axios核心原理,再也不怕面試官問我Axios原理

開發 前端
Axios 是一個基于 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。axios可以用在瀏覽器和 node.js 中是因為,它會自動判斷當前環境是什么,如果是瀏覽器,就會基于XMLHttpRequests實現axios。

 手寫axios核心原理

  • 手寫axios核心原理,再也不怕面試官問我axios原理
  • 手寫axios核心原理

一、axios簡介

  • axios是什么?
  • axios有什么特性?(不得不說面試被問到幾次)

二、基本使用方式

三、實現axios和axios.method

四、請求和響應攔截器

  • 首先
  • 接下來,再執行
  • 接下來,再執行

 

一、axios簡介
axios是什么?
Axios 是一個基于 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。

axios有什么特性?(不得不說面試被問到幾次)

  • 從瀏覽器中創建 XMLHttpRequests從 node.js
  • 創建 http 請求
  • 支持 Promise API
  • 攔截請求和響應轉換請求數據和響應數據
  • 取消請求
  • 自動轉換JSON 數據
  • 客戶端支持防御 XSRF

實際上,axios可以用在瀏覽器和 node.js 中是因為,它會自動判斷當前環境是什么,如果是瀏覽器,就會基于XMLHttpRequests實現axios。如果是node.js環境,就會基于node內置核心模塊http實現axios簡單來說,axios的基本原理就是

  1. axios還是屬于 XMLHttpRequest, 因此需要實現一個ajax。或者基于http 。
  2. 還需要一個promise對象來對結果進行處理。

有什么不理解的或者是建議歡迎評論提出.項目已經放到github.可以的話給個star吧!謝謝 github:https://github.com/Sunny-lucking/howToBuildMyAxios

二、基本使用方式
axios基本使用方式主要有

  1. axios(config)
  2. axios.method(url, data , config)
  1. // index.html文件 
  2. <html> 
  3. <script type="text/javascript" src="./myaxios.js"></script> 
  4. <body> 
  5. <button class="btn">點我發送請求</button> 
  6. <script> 
  7.     document.querySelector('.btn').onclick = function() { 
  8.         // 分別使用以下方法調用,查看myaxios的效果 
  9.         axios.post('/postAxios', { 
  10.           name'小美post' 
  11.         }).then(res => { 
  12.           console.log('postAxios 成功響應', res); 
  13.         }) 
  14.  
  15.         axios({ 
  16.           method: 'post'
  17.           url: '/getAxios' 
  18.         }).then(res => { 
  19.           console.log('getAxios 成功響應', res); 
  20.         }) 
  21.     } 
  22. </script> 
  23. </body> 
  24. </html> 
  25. </html> 

三、實現axios和axios.method
從axios(config)的使用上可以看出導出的axios是一個方法。從axios.method(url, data , config)的使用可以看出導出的axios上或者原型上掛有get,post等方法。

實際上導出的axios就是一個Axios類中的一個方法。

如代碼所以,核心代碼是request。我們把request導出,就可以使用axios(config)這種形式來調用axios了。

  1. class Axios { 
  2.     constructor() { 
  3.  
  4.     } 
  5.  
  6.     request(config) { 
  7.         return new Promise(resolve => { 
  8.             const {url = '', method = 'get', data = {}} = config; 
  9.             // 發送ajax請求 
  10.             const xhr = new XMLHttpRequest(); 
  11.             xhr.open(method, url, true); 
  12.             xhr.onload = function() { 
  13.                 console.log(xhr.responseText) 
  14.                 resolve(xhr.responseText); 
  15.             } 
  16.             xhr.send(data); 
  17.         }) 
  18.     } 

怎么導出呢?十分簡單,new Axios,獲得axios實例,再獲得實例上的request方法就好了。

  1. // 最終導出axios的方法,即實例的request方法 
  2. function CreateAxiosFn() { 
  3.     let axios = new Axios(); 
  4.     let req = axios.request.bind(axios); 
  5.     return req; 
  1. // 得到最后的全局變量axios 
  2. let axios = CreateAxiosFn(); 

點擊查看此時的myAxios.js

現在axios實際上就是request方法。

你可能會很疑惑,因為我當初看源碼的時候也很疑惑:干嘛不直接寫個request方法,然后導出呢?非得這樣繞這么大的彎子。別急。后面慢慢就會講到。

現在一個簡單的axios就完成了,我們來引入myAxios.js文件并測試一下可以使用不?

簡單的搭建服務器:

  1. //server.js 
  2. var express = require('express'); 
  3. var app = express(); 
  4.  
  5. //設置允許跨域訪問該服務. 
  6. app.all('*'function (req, res, next) { 
  7.     res.header('Access-Control-Allow-Origin''*'); 
  8.     res.header('Access-Control-Allow-Headers''Content-Type'); 
  9.     res.header('Access-Control-Allow-Methods''*'); 
  10.     res.header('Content-Type''application/json;charset=utf-8'); 
  11.     next(); 
  12. }); 
  13.  
  14. app.get('/getTest'function(request, response){ 
  15.     data = { 
  16.         'FrontEnd':'前端'
  17.         'Sunny':'陽光' 
  18.     }; 
  19.     response.json(data); 
  20. }); 
  21. var server = app.listen(5000, function(){ 
  22.     console.log("服務器啟動"); 
  23. }); 
  1. //index.html 
  2. <script type="text/javascript" src="./myAxios.js"></script> 
  3.  
  4. <body> 
  5. <button class="btn">點我發送請求</button> 
  6. <script> 
  7.     document.querySelector('.btn').onclick = function() { 
  8.         // 分別使用以下方法調用,查看myaxios的效果 
  9.         axios({ 
  10.           method: 'get'
  11.           url: 'http://localhost:5000/getTest' 
  12.         }).then(res => { 
  13.           console.log('getAxios 成功響應', res); 
  14.         }) 
  15.     } 
  16. </script> 
  17. </body> 

點擊按鈕,看看是否能成功獲得數據。

發現確實成功。

可喜可賀

現在我們來實現下axios.method()的形式。

思路:我們可以再Axios.prototype添加這些方法。而這些方法內部調用request方法即可,如代碼所示:

  1. // 定義get,post...方法,掛在到Axios原型上 
  2. const methodsArr = ['get''delete''head''options''put''patch''post']; 
  3. methodsArr.forEach(met => { 
  4.     Axios.prototype[met] = function() { 
  5.         console.log('執行'+met+'方法'); 
  6.         // 處理單個方法 
  7.         if (['get''delete''head''options'].includes(met)) { // 2個參數(url[, config]) 
  8.             return this.request({ 
  9.                 method: met, 
  10.                 url: arguments[0], 
  11.                 ...arguments[1] || {} 
  12.             }) 
  13.         } else { // 3個參數(url[,data[,config]]) 
  14.             return this.request({ 
  15.                 method: met, 
  16.                 url: arguments[0], 
  17.                 data: arguments[1] || {}, 
  18.                 ...arguments[2] || {} 
  19.             }) 
  20.         } 
  21.  
  22.     } 
  23. }) 

我們通過遍歷methodsArr數組,依次在Axios.prototype添加對應的方法,注意的是'get', 'delete', 'head', 'options'這些方法只接受兩個參數。而其他的可接受三個參數,想一下也知道,get不把參數放body的。

但是,你有沒有發現,我們只是在Axios的prototype上添加對應的方法,我們導出去的可是request方法啊,那怎么辦?簡單,把Axios.prototype上的方法搬運到request上即可。

我們先來實現一個工具方法,實現將b的方法混入a;

  1. const utils = { 
  2.   extend(a,b, context) { 
  3.     for(let key in b) { 
  4.       if (b.hasOwnProperty(key)) { 
  5.         if (typeof b[key] === 'function') { 
  6.           a[key] = b[key].bind(context); 
  7.         } else { 
  8.           a[key] = b[key
  9.         } 
  10.       } 
  11.        
  12.     } 
  13.   } 

然后我們就可以利用這個方法將Axios.prototype上的方法搬運到request上啦。

我們修改一下之前的CreateAxiosFn方法即可

  1. function CreateAxiosFn() { 
  2.   let axios = new Axios(); 
  3.    
  4.   let req = axios.request.bind(axios); 
  5.   增加代碼 
  6.   utils.extend(req, Axios.prototype, axios) 
  7.    
  8.   return req; 

點擊查看此時的myAxios.js

現在來測試一下能不能使用axios.get()這種形式調用axios。

  1. <body> 
  2. <button class="btn">點我發送請求</button> 
  3. <script> 
  4.     document.querySelector('.btn').onclick = function() { 
  5.  
  6.         axios.get('http://localhost:5000/getTest'
  7.             .then(res => { 
  8.                  console.log('getAxios 成功響應', res); 
  9.             }) 
  10.  
  11.     } 
  12. </script> 
  13. </body> 

又是意料之中成功。再完成下一個功能之前,先給上目前myAxios.js的完整代碼

  1. class Axios { 
  2.     constructor() { 
  3.  
  4.     } 
  5.  
  6.     request(config) { 
  7.         return new Promise(resolve => { 
  8.             const {url = '', method = 'get', data = {}} = config; 
  9.             // 發送ajax請求 
  10.             console.log(config); 
  11.             const xhr = new XMLHttpRequest(); 
  12.             xhr.open(method, url, true); 
  13.             xhr.onload = function() { 
  14.                 console.log(xhr.responseText) 
  15.                 resolve(xhr.responseText); 
  16.             } 
  17.             xhr.send(data); 
  18.         }) 
  19.     } 
  20.  
  21. // 定義get,post...方法,掛在到Axios原型上 
  22. const methodsArr = ['get''delete''head''options''put''patch''post']; 
  23. methodsArr.forEach(met => { 
  24.     Axios.prototype[met] = function() { 
  25.         console.log('執行'+met+'方法'); 
  26.         // 處理單個方法 
  27.         if (['get''delete''head''options'].includes(met)) { // 2個參數(url[, config]) 
  28.             return this.request({ 
  29.                 method: met, 
  30.                 url: arguments[0], 
  31.                 ...arguments[1] || {} 
  32.             }) 
  33.         } else { // 3個參數(url[,data[,config]]) 
  34.             return this.request({ 
  35.                 method: met, 
  36.                 url: arguments[0], 
  37.                 data: arguments[1] || {}, 
  38.                 ...arguments[2] || {} 
  39.             }) 
  40.         } 
  41.  
  42.     } 
  43. }) 
  44.  
  45.  
  46. // 工具方法,實現b的方法或屬性混入a; 
  47. // 方法也要混入進去 
  48. const utils = { 
  49.   extend(a,b, context) { 
  50.     for(let key in b) { 
  51.       if (b.hasOwnProperty(key)) { 
  52.         if (typeof b[key] === 'function') { 
  53.           a[key] = b[key].bind(context); 
  54.         } else { 
  55.           a[key] = b[key
  56.         } 
  57.       } 
  58.        
  59.     } 
  60.   } 
  61.  
  62.  
  63. // 最終導出axios的方法-》即實例的request方法 
  64. function CreateAxiosFn() { 
  65.     let axios = new Axios(); 
  66.  
  67.     let req = axios.request.bind(axios); 
  68.     // 混入方法, 處理axios的request方法,使之擁有get,post...方法 
  69.     utils.extend(req, Axios.prototype, axios) 
  70.     return req; 
  71.  
  72. // 得到最后的全局變量axios 
  73. let axios = CreateAxiosFn(); 

四、請求和響應攔截器
我們先看下攔截器的使用

  1. // 添加請求攔截器 
  2. axios.interceptors.request.use(function (config) { 
  3.     // 在發送請求之前做些什么 
  4.     return config; 
  5.   }, function (error) { 
  6.     // 對請求錯誤做些什么 
  7.     return Promise.reject(error); 
  8.   }); 
  9.  
  10. // 添加響應攔截器 
  11. axios.interceptors.response.use(function (response) { 
  12.     // 對響應數據做點什么 
  13.     return response; 
  14.   }, function (error) { 
  15.     // 對響應錯誤做點什么 
  16.     return Promise.reject(error); 
  17.   }); 

攔截器是什么意思呢?其實就是在我們發送一個請求的時候會先執行請求攔截器的代碼,然后再真正地執行我們發送的請求,這個過程會對config,也就是我們發送請求時傳送的參數進行一些操作。

而當接收響應的時候,會先執行響應攔截器的代碼,然后再把響應的數據返回來,這個過程會對response,也就是響應的數據進行一系列操作。

怎么實現呢?需要明確的是攔截器也是一個類,管理響應和請求。因此我們先實現攔截器

  1. class InterceptorsManage { 
  2.   constructor() { 
  3.     this.handlers = []; 
  4.   } 
  5.  
  6.   use(fullfield, rejected) { 
  7.     this.handlers.push({ 
  8.       fullfield, 
  9.       rejected 
  10.     }) 
  11.   } 

我們是用這個語句axios.interceptors.response.use和axios.interceptors.request.use,來觸發攔截器執行use方法的。

說明axios上有一個響應攔截器和一個請求攔截器。那怎么實現Axios呢?看代碼

  1. class Axios { 
  2.     constructor() { 
  3.         新增代碼 
  4.         this.interceptors = { 
  5.             request: new InterceptorsManage, 
  6.             response: new InterceptorsManage 
  7.         } 
  8.     } 
  9.  
  10.     request(config) { 
  11.         return new Promise(resolve => { 
  12.             const {url = '', method = 'get', data = {}} = config; 
  13.             // 發送ajax請求 
  14.             console.log(config); 
  15.             const xhr = new XMLHttpRequest(); 
  16.             xhr.open(method, url, true); 
  17.             xhr.onload = function() { 
  18.                 console.log(xhr.responseText) 
  19.                 resolve(xhr.responseText); 
  20.             }; 
  21.             xhr.send(data); 
  22.         }) 
  23.     } 

可見,axios實例上有一個對象interceptors。這個對象有兩個攔截器,一個用來處理請求,一個用來處理響應。

所以,我們執行語句axios.interceptors.response.use和axios.interceptors.request.use的時候,實現獲取axios實例上的interceptors對象,然后再獲取response或request攔截器,再執行對應的攔截器的use方法。

而執行use方法,會把我們傳入的回調函數push到攔截器的handlers數組里。

到這里你有沒有發現一個問題。這個interceptors對象是Axios上的啊,我們導出的是request方法啊(欸?好熟悉的問題,上面提到過哈哈哈~~~額)。處理方法跟上面處理的方式一樣,都是把Axios上的方法和屬性搬到request過去,也就是遍歷Axios實例上的方法,得以將interceptors對象掛載到request上。

所以只要更改下CreateAxiosFn方法即可。

  1. function CreateAxiosFn() { 
  2.   let axios = new Axios(); 
  3.    
  4.   let req = axios.request.bind(axios); 
  5.   // 混入方法, 處理axios的request方法,使之擁有get,post...方法 
  6.   utils.extend(req, Axios.prototype, axios) 
  7.   新增代碼 
  8.   utils.extend(req, axios) 
  9.   return req; 

好了,現在request也有了interceptors對象,那么什么時候拿interceptors對象中的handler之前保存的回調函數出來執行。

沒錯,就是我們發送請求的時候,會先獲取request攔截器的handlers的方法來執行。再執行我們發送的請求,然后獲取response攔截器的handlers的方法來執行。

因此,我們要修改之前所寫的request方法 之前是這樣的。

  1. request(config) { 
  2.     return new Promise(resolve => { 
  3.         const {url = '', method = 'get', data = {}} = config; 
  4.         // 發送ajax請求 
  5.         console.log(config); 
  6.         const xhr = new XMLHttpRequest(); 
  7.         xhr.open(method, url, true); 
  8.         xhr.onload = function() { 
  9.             console.log(xhr.responseText) 
  10.             resolve(xhr.responseText); 
  11.         }; 
  12.         xhr.send(data); 
  13.     }) 

但是現在request里不僅要執行發送ajax請求,還要執行攔截器handlers中的回調函數。所以,最好下就是將執行ajax的請求封裝成一個方法

  1. request(config) { 
  2.     this.sendAjax(config) 
  3. sendAjax(config){ 
  4.     return new Promise(resolve => { 
  5.         const {url = '', method = 'get', data = {}} = config; 
  6.         // 發送ajax請求 
  7.         console.log(config); 
  8.         const xhr = new XMLHttpRequest(); 
  9.         xhr.open(method, url, true); 
  10.         xhr.onload = function() { 
  11.             console.log(xhr.responseText) 
  12.             resolve(xhr.responseText); 
  13.         }; 
  14.         xhr.send(data); 
  15.     }) 

好了,現在我們要獲得handlers中的回調

  1. request(config) { 
  2.     // 攔截器和請求組裝隊列 
  3.     let chain = [this.sendAjax.bind(this), undefined] // 成對出現的,失敗回調暫時不處理 
  4.  
  5.     // 請求攔截 
  6.     this.interceptors.request.handlers.forEach(interceptor => { 
  7.         chain.unshift(interceptor.fullfield, interceptor.rejected) 
  8.     }) 
  9.  
  10.     // 響應攔截 
  11.     this.interceptors.response.handlers.forEach(interceptor => { 
  12.         chain.push(interceptor.fullfield, interceptor.rejected) 
  13.     }) 
  14.  
  15.     // 執行隊列,每次執行一對,并給promise賦最新的值 
  16.     let promise = Promise.resolve(config); 
  17.     while(chain.length > 0) { 
  18.         promise = promise.then(chain.shift(), chain.shift()) 
  19.     } 
  20.     return promise; 

我們先把sendAjax請求和undefined放進了chain數組里,再把請求攔截器的handlers的成對回調放到chain數組頭部。再把響應攔截器的handlers的承兌回調反倒chain數組的尾部。

然后再 逐漸取數 chain數組的成對回調執行。

  1. promise = promise.then(chain.shift(), chain.shift()) 

這一句,實際上就是不斷將config從上一個promise傳遞到下一個promise,期間可能回調config做出一些修改。什么意思?我們結合一個例子來講解一下

首先攔截器是這樣使用的

  1. // 添加請求攔截器 
  2.  
  3. axios.interceptors.request.use(function (config) { 
  4.     // 在發送請求之前做些什么 
  5.     return config; 
  6.   }, function (error) { 
  7.     // 對請求錯誤做些什么 
  8.     return Promise.reject(error); 
  9.   }); 
  10.  
  11. // 添加響應攔截器 
  12. axios.interceptors.response.use(function (response) { 
  13.     // 對響應數據做點什么 
  14.     return response; 
  15.   }, function (error) { 
  16.     // 對響應錯誤做點什么 
  17.     return Promise.reject(error); 
  18.   }); 

然后執行request的時候。chain數組的數據是這樣的

  1. chain = [ 
  2.   function (config) { 
  3.     // 在發送請求之前做些什么 
  4.     return config; 
  5.   },  
  6.    
  7.   function (error) { 
  8.     // 對請求錯誤做些什么 
  9.     return Promise.reject(error); 
  10.   } 
  11.   this.sendAjax.bind(this),  
  12.    
  13.   undefined, 
  14.    
  15.   function (response) { 
  16.     // 對響應數據做點什么 
  17.     return response; 
  18.   },  
  19.   function (error) { 
  20.     // 對響應錯誤做點什么 
  21.     return Promise.reject(error); 
  22.   } 

首先
執行第一次promise.then(chain.shift(), chain.shift()),即

  1. promise.then
  2.   function (config) { 
  3.     // 在發送請求之前做些什么 
  4.     return config; 
  5.   },  
  6.    
  7.   function (error) { 
  8.     // 對請求錯誤做些什么 
  9.     return Promise.reject(error); 
  10.   } 

一般情況,promise是resolved狀態,是執行成功回調的,也就是執行

  1. function (config) { 
  2.     // 在發送請求之前做些什么 
  3.     return config; 
  4.   },  

promise.then是要返回一個新的promise對象的。為了區分,在這里,我會把這個新的promise對象叫做第一個新的promise對象 這個第一個新的promise對象會把

  1. function (config) { 
  2.     // 在發送請求之前做些什么 
  3.     return config; 
  4.   },  

的執行結果傳入resolve函數中

  1. resolve(config) 

使得這個返回的第一個新的promise對象的狀態為resovled,而且第一個新的promise對象的data為config。

這里需要對Promise的原理足夠理解。所以我前一篇文章寫的是手寫Promise核心原理,再也不怕面試官問我Promise原理,你可以去看看

接下來,再執行

  1. promise.then
  2.   sendAjax(config) 
  3.   , 
  4.   undefined 

注意:這里的promise是 上面提到的第一個新的promise對象。

而promise.then這個的執行又會返回第二個新的promise對象。

因為這里promise.then中的promise也就是第一個新的promise對象的狀態是resolved的,所以會執行sendAjax()。而且會取出第一個新的promise對象的data 作為config轉入sendAjax()。

當sendAjax執行完,就會返回一個response。這個response就會保存在第二個新的promise對象的data中。

接下來,再執行

  1. promise.then
  2.   function (response) { 
  3.     // 對響應數據做點什么 
  4.     return response; 
  5.   },  
  6.   function (error) { 
  7.     // 對響應錯誤做點什么 
  8.     return Promise.reject(error); 
  9.   } 

同樣,會把第二個新的promise對象的data取出來作為response參數傳入

  1. function (response) { 
  2.     // 對響應數據做點什么 
  3.     return response; 
  4.   },  

飯后返回一個promise對象,這個promise對象的data保存了這個函數的執行結果,也就是返回值response。

然后通過return promise;

把這個promise返回了。咦?是怎么取出promise的data的。我們看看我們平常事怎么獲得響應數據的

  1. axios.get('http://localhost:5000/getTest'
  2.     .then(res => { 
  3.          console.log('getAxios 成功響應', res); 
  4.     }) 

在then里接收響應數據。所以原理跟上面一樣,將返回的promise的data作為res參數了。

現在看看我們的myAxios完整代碼吧,好有個全面的了解

  1. class InterceptorsManage { 
  2.     constructor() { 
  3.         this.handlers = []; 
  4.     } 
  5.  
  6.     use(fullfield, rejected) { 
  7.         this.handlers.push({ 
  8.             fullfield, 
  9.             rejected 
  10.         }) 
  11.     } 
  12.  
  13. class Axios { 
  14.     constructor() { 
  15.         this.interceptors = { 
  16.             request: new InterceptorsManage, 
  17.             response: new InterceptorsManage 
  18.         } 
  19.     } 
  20.  
  21.     request(config) { 
  22.         // 攔截器和請求組裝隊列 
  23.         let chain = [this.sendAjax.bind(this), undefined] // 成對出現的,失敗回調暫時不處理 
  24.  
  25.         // 請求攔截 
  26.         this.interceptors.request.handlers.forEach(interceptor => { 
  27.             chain.unshift(interceptor.fullfield, interceptor.rejected) 
  28.         }) 
  29.  
  30.         // 響應攔截 
  31.         this.interceptors.response.handlers.forEach(interceptor => { 
  32.             chain.push(interceptor.fullfield, interceptor.rejected) 
  33.         }) 
  34.  
  35.         // 執行隊列,每次執行一對,并給promise賦最新的值 
  36.         let promise = Promise.resolve(config); 
  37.         while(chain.length > 0) { 
  38.             promise = promise.then(chain.shift(), chain.shift()) 
  39.         } 
  40.         return promise; 
  41.     } 
  42.     sendAjax(){ 
  43.         return new Promise(resolve => { 
  44.             const {url = '', method = 'get', data = {}} = config; 
  45.             // 發送ajax請求 
  46.             console.log(config); 
  47.             const xhr = new XMLHttpRequest(); 
  48.             xhr.open(method, url, true); 
  49.             xhr.onload = function() { 
  50.                 console.log(xhr.responseText) 
  51.                 resolve(xhr.responseText); 
  52.             }; 
  53.             xhr.send(data); 
  54.         }) 
  55.     } 
  56.  
  57. // 定義get,post...方法,掛在到Axios原型上 
  58. const methodsArr = ['get''delete''head''options''put''patch''post']; 
  59. methodsArr.forEach(met => { 
  60.     Axios.prototype[met] = function() { 
  61.         console.log('執行'+met+'方法'); 
  62.         // 處理單個方法 
  63.         if (['get''delete''head''options'].includes(met)) { // 2個參數(url[, config]) 
  64.             return this.request({ 
  65.                 method: met, 
  66.                 url: arguments[0], 
  67.                 ...arguments[1] || {} 
  68.             }) 
  69.         } else { // 3個參數(url[,data[,config]]) 
  70.             return this.request({ 
  71.                 method: met, 
  72.                 url: arguments[0], 
  73.                 data: arguments[1] || {}, 
  74.                 ...arguments[2] || {} 
  75.             }) 
  76.         } 
  77.  
  78.     } 
  79. }) 
  80.  
  81.  
  82. // 工具方法,實現b的方法混入a; 
  83. // 方法也要混入進去 
  84. const utils = { 
  85.     extend(a,b, context) { 
  86.         for(let key in b) { 
  87.             if (b.hasOwnProperty(key)) { 
  88.                 if (typeof b[key] === 'function') { 
  89.                     a[key] = b[key].bind(context); 
  90.                 } else { 
  91.                     a[key] = b[key
  92.                 } 
  93.             } 
  94.  
  95.         } 
  96.     } 
  97.  
  98.  
  99. // 最終導出axios的方法-》即實例的request方法 
  100. function CreateAxiosFn() { 
  101.     let axios = new Axios(); 
  102.  
  103.     let req = axios.request.bind(axios); 
  104.     // 混入方法, 處理axios的request方法,使之擁有get,post...方法 
  105.     utils.extend(req, Axios.prototype, axios) 
  106.     return req; 
  107.  
  108. // 得到最后的全局變量axios 
  109. let axios = CreateAxiosFn(); 

來測試下攔截器功能是否正常

  1. <script type="text/javascript" src="./myAxios.js"></script> 
  2.  
  3. <body> 
  4. <button class="btn">點我發送請求</button> 
  5. <script> 
  6.     // 添加請求攔截器 
  7.     axios.interceptors.request.use(function (config) { 
  8.         // 在發送請求之前做些什么 
  9.         config.method = "get"
  10.         console.log("被我請求攔截器攔截了,哈哈:",config); 
  11.         return config; 
  12.     }, function (error) { 
  13.         // 對請求錯誤做些什么 
  14.         return Promise.reject(error); 
  15.     }); 
  16.  
  17.     // 添加響應攔截器 
  18.     axios.interceptors.response.use(function (response) { 
  19.         // 對響應數據做點什么 
  20.         console.log("被我響應攔截攔截了,哈哈 "); 
  21.         response = {message:"響應數據被我替換了,啊哈哈哈"
  22.         return response; 
  23.     }, function (error) { 
  24.         // 對響應錯誤做點什么 
  25.         console.log("錯了嗎"); 
  26.         return Promise.reject(error); 
  27.     }); 
  28.     document.querySelector('.btn').onclick = function() { 
  29.         // 分別使用以下方法調用,查看myaxios的效果 
  30.         axios({ 
  31.           url: 'http://localhost:5000/getTest' 
  32.         }).then(res => { 
  33.           console.log('response', res); 
  34.         }) 
  35.     } 
  36. </script> 
  37. </body> 

攔截成功!!!!!

 

責任編輯:姜華 來源: 前端陽光
相關推薦

2021-08-10 18:36:02

Express原理面試

2020-11-24 07:48:32

React

2022-08-27 13:49:36

ES7promiseresolve

2020-10-23 09:26:57

React-Redux

2021-05-08 07:53:33

面試線程池系統

2022-04-01 07:52:42

JavaScript防抖節流

2020-12-03 08:14:45

Axios核心Promise

2022-10-31 11:10:49

Javavolatile變量

2021-11-24 10:10:32

axios前端攔截器

2023-11-28 17:49:51

watch?computed?性能

2020-10-15 12:52:46

SpringbootJava編程語言

2021-04-22 07:49:51

Vue3Vue2.xVue3.x

2025-07-18 07:19:00

2024-03-05 10:33:39

AOPSpring編程

2024-08-22 10:39:50

@Async注解代理

2025-03-07 00:00:10

2020-12-09 10:29:53

SSH加密數據安全

2021-12-02 08:19:06

MVCC面試數據庫

2020-11-02 09:35:04

ReactHook

2024-02-29 16:49:20

volatileJava并發編程
點贊
收藏

51CTO技術棧公眾號

成人午夜一级二级三级| 亚洲人成在线观| 日本一本中文字幕| 四虎成人免费在线| 日韩av电影天堂| 久久久国产成人精品| 污污免费在线观看| 韩国成人在线| 一区二区三区影院| 久久久www免费人成黑人精品| 懂色av中文字幕| 影音先锋成人在线电影| 亚洲精品av在线播放| 激情综合网俺也去| 欧美日韩经典丝袜| 欧美国产精品一区二区三区| 成人综合av网| 中文字字幕在线中文乱码| 91久久中文| 久久中文精品视频| 国产三级视频网站| 一本一道久久a久久| 欧美午夜不卡视频| 亚洲熟妇无码一区二区三区| 毛片在线看网站| 久久精品人人爽人人爽| 99影视tv| 国产内射老熟女aaaa∵| 日本亚洲三级在线| 青青久久av北条麻妃海外网| 欧美日韩偷拍视频| 国产精品久久久久一区二区三区厕所| 精品无人区乱码1区2区3区在线 | 蜜桃网站成人| 精品黑人一区二区三区在线观看| 奇米精品一区二区三区四区| 欧美又大又粗又长| 可以免费看的av毛片| 国内精品99| 欧美激情精品久久久久久黑人| 亚洲av无一区二区三区| 精品国产91| 亚洲日本欧美日韩高观看| 国产xxxxxxxxx| 国产ts一区| 精品成人佐山爱一区二区| 日本r级电影在线观看| 国产成人77亚洲精品www| 欧美怡红院视频| 日本老熟妇毛茸茸| 91九色综合| 欧美三级中文字幕| 国内外成人免费在线视频| 99只有精品| 欧美丝袜自拍制服另类| 日韩一区二区三区不卡视频| 嫩草伊人久久精品少妇av杨幂| 色屁屁一区二区| 日韩中文字幕二区| 秋霞国产精品| 欧美日韩高清影院| 久久成年人网站| 日本免费一区二区三区视频| 日韩欧美国产小视频| 一级全黄裸体片| 国产suv精品一区二区四区视频| 亚洲高清在线观看| 中文字幕高清视频| 日韩精品免费一区二区三区| 日韩在线高清视频| 欧美黄片一区二区三区| 亚洲国产高清视频| 国产va免费精品高清在线观看 | 日韩经典中文字幕一区| 国产精品久久久久av| 在线观看日韩一区二区| 国产精品一二三区| 国模精品娜娜一二三区| 国内在线精品| 亚洲黄色小说网站| 99视频在线免费播放| 欧美一级大片| 欧美丰满一区二区免费视频| 久久无码专区国产精品s| 欧美综合精品| www.欧美三级电影.com| 久青草视频在线观看| 久久国产福利| 成人性生交xxxxx网站| 三级网站免费观看| 国产精品女同一区二区三区| 成人午夜免费剧场| 蜜臀国产一区| 日韩视频一区二区三区| 日本aaa视频| 亚洲欧美综合久久久| 午夜精品理论片| 亚洲一区在线观| 99久久久精品| 国产精品99久久久久久大便| 午夜激情在线播放| 777欧美精品| 美国黄色一级毛片| 亚洲经典一区| 国产精品你懂得| 人妻精品无码一区二区| 国产精品第13页| 中国丰满人妻videoshd| 日日狠狠久久| 亚洲欧美日韩成人| 精品无码人妻一区二区三区品| 日韩高清在线电影| 精品日本一区二区三区在线观看 | 自拍偷拍一区| 欧美激情一区二区三区久久久| 波多野结衣在线观看视频| 国产宾馆实践打屁股91| 亚洲精品免费在线看| 女海盗2成人h版中文字幕| 欧美一区二区三区精品| 你懂得视频在线观看| 午夜亚洲激情| 国产一区在线免费| 怡红院av在线| 91麻豆精品国产91久久久久| 中字幕一区二区三区乱码| 国产精品久久久免费| 国产高清精品一区| 日韩精品卡一| 91精品国产综合久久福利 | 91九色精品| 国产精品色午夜在线观看| 色视频免费在线观看| 亚洲国产精品视频| 曰本三级日本三级日本三级| 国产精品久久久乱弄| 国产精品中文字幕在线| 成人在线视频成人| 日韩欧美亚洲成人| 久久久久久久久免费看无码| 国产精品一二| 久久天天狠狠| 亚洲天堂资源| 亚洲欧美精品一区二区| 波多野结衣啪啪| 久久久三级国产网站| 黄色动漫在线免费看| 日韩丝袜视频| 欧美专区中文字幕| 欧美美乳在线| 色婷婷av一区二区三区gif | 亚洲美女屁股眼交3| 99九九99九九九99九他书对| 99精品视频在线观看免费播放| 国产精品永久免费| 国产网友自拍视频导航网站在线观看| 欧美群妇大交群中文字幕| 亚洲色图100p| 国产一区二区在线观看视频| 久操手机在线视频| 高清精品xnxxcom| 欧美又大又粗又长| 精品乱码一区二区三四区视频| 日本道免费精品一区二区三区| 制服 丝袜 综合 日韩 欧美| 免费av成人在线| 日本黄色播放器| 2020国产精品极品色在线观看| 欧美极度另类性三渗透| 日韩午夜影院| 欧美日韩一区二区三区视频| 日韩成人短视频| 成人污污视频在线观看| 欧美色图另类小说| 91视频久久| 国产伦精品一区二区三区| 午夜影院一区| 久久韩剧网电视剧| 乱精品一区字幕二区| 色综合久久综合网欧美综合网 | 国产suv精品一区二区| 午夜免费福利在线观看| 精品国产一区二区三区久久久蜜月| 日本最新中文字幕| 中文字幕 久热精品 视频在线| 久久精品一卡二卡| 一本综合精品| 色乱码一区二区三区熟女| 国产福利一区二区精品秒拍| 国产成人鲁鲁免费视频a| 黄色网在线播放| 日韩av网站大全| 国产精品无码免费播放| 精品国产乱码久久久久久天美| av片在线免费看| 99热99精品| 国产永久免费网站| 久久精品综合| 日本人妻伦在线中文字幕| 精品国产一区二区三区久久久樱花 | 99国产精品久久| 最新av免费在线观看| 亚洲在线电影| 国产情侣第一页| 日韩一区三区| 欧美另类高清视频在线| 中文字幕亚洲在线观看| 国产免费成人av| 中文字幕色婷婷在线视频| 欧美日本黄视频| av播放在线| 亚洲人成人99网站| 无码精品一区二区三区在线 | 天堂中文资源在线观看| 制服丝袜亚洲网站| 真实新婚偷拍xxxxx| 欧美性猛交99久久久久99按摩| 青娱乐国产精品| 国产精品家庭影院| 国产三级av在线播放| 94色蜜桃网一区二区三区| 337p日本欧洲亚洲大胆张筱雨| 看电视剧不卡顿的网站| 日韩a在线播放| 亚洲精品综合| 成人性生活视频免费看| 欧美久久一级| 青青草原网站在线观看| 婷婷亚洲最大| 一区二区三区在线观看www| 成人高清电影网站| 色综合久久av| 大色综合视频网站在线播放| 欧美日本韩国一区二区三区| 午夜欧洲一区| 欧美一区二视频在线免费观看| 亚洲国产欧美日韩在线观看第一区| 国产伦精品一区二区三区视频免费 | 欧美一区二区播放| 国产精品毛片一区视频播| 欧美精品v国产精品v日韩精品 | 色午夜这里只有精品| 成人综合影院| www国产精品视频| 国产原创视频在线观看| 美女999久久久精品视频| 在线观看电影av| 欧美激情一区二区三区高清视频| 欧美videos另类精品| 欧美精品久久一区二区| 99re6在线精品视频免费播放| 久久久久久成人精品| 91福利在线免费| 欧美在线视频观看免费网站| 欧美成人影院| 国产精品专区一| 精品视频91| 国产日韩欧美二区| 九九视频精品全部免费播放| 日韩av电影免费在线| 久久综合99| 免费看日本黄色| 国产亚洲精品v| 992kp快乐看片永久免费网址| 日韩不卡手机在线v区| 性欧美在线视频| 成人一区二区三区在线观看| 久久久久9999| 国产精品嫩草影院com| www.超碰在线观看| 五月综合激情日本mⅴ| 黄色av网站免费观看| 欧美丰满美乳xxx高潮www| 亚洲精品一区二区三区蜜桃| 日韩高清免费在线| 香蕉视频免费在线播放| 欧美丰满少妇xxxxx做受| 亚洲精品国产精品国产| 国产在线观看精品| gogo人体一区| 色播五月综合| 国产精品magnet| 污污视频网站免费观看| 国产精品一级片| 一道本在线观看| 亚洲精品日韩综合观看成人91| 国产精品100| 69精品人人人人| 免费a在线观看| 九色精品免费永久在线| 婷婷六月国产精品久久不卡| 91在线播放视频| 成人区精品一区二区婷婷| av在线com| 久热成人在线视频| 亚洲制服丝袜在线播放| 成人欧美一区二区三区黑人麻豆| 亚洲精品视频在线观看免费视频| 欧美狂野另类xxxxoooo| 欧美中文在线| 欧美精品九九久久| 日韩在线电影| 四虎一区二区| 国产日韩1区| 在线观看你懂的视频| 国产精品蜜臀av| 潘金莲一级淫片aaaaaa播放| 日韩欧美一区电影| 成年人免费在线视频| 91av在线国产| 99久久香蕉| 麻豆一区二区三区在线观看| 日韩成人一级大片| 日本丰满少妇裸体自慰| 亚洲一区二区三区在线看| 91麻豆成人精品国产免费网站| 国产午夜精品理论片a级探花| 欧美理论片在线播放| 亚洲自拍偷拍区| 99久久夜色精品国产亚洲狼 | 国产91精品欧美| www.av成人| 精品婷婷伊人一区三区三| 日本不卡免费播放| 国内久久久精品| 成人av婷婷| www国产无套内射com| 国产精品一区二区视频| www.av免费| 91精品麻豆日日躁夜夜躁| 欧美另类极品| 国产视频999| 99国产精品免费视频观看| 国产免费又粗又猛又爽| 国产欧美精品国产国产专区 | 日韩精品一区二区在线| 九七电影韩国女主播在线观看| 国产啪精品视频| 99精品在线观看| 九九九九九国产| 亚洲视频免费观看| 国产av精国产传媒| 久久99国产精品自在自在app | 精品一区二区三区免费观看| 亚洲不卡的av| 欧美精品乱人伦久久久久久| 黄色精品在线观看| 亚洲一区制服诱惑| 欧美午夜影院| 自拍视频一区二区| 欧美日韩亚洲网| 国产黄在线看| 成人福利在线视频| 欧美日韩国产高清| 无码成人精品区在线观看| 午夜激情久久久| 韩国中文免费在线视频| 国产精品视频色| 午夜国产精品视频免费体验区| 亚洲精品鲁一鲁一区二区三区| 亚洲mv大片欧洲mv大片精品| 午夜福利理论片在线观看| 欧美在线视频导航| 91嫩草亚洲精品| zjzjzjzjzj亚洲女人| 精品动漫一区二区三区| 国产色a在线| 日韩免费成人网| 丝袜综合欧美| 国产综合第一页| 老司机精品视频网站| 老司机精品免费视频| 日韩欧美亚洲另类制服综合在线 | 欧美视频导航| 91精品国产自产| 欧美群妇大交群中文字幕| 国模雨婷捆绑高清在线| 欧美日韩一区在线观看视频| 久久99精品久久久久久| 国产一级av毛片| 亚洲人精选亚洲人成在线| 国产精品国产亚洲精品| www.浪潮av.com| 日韩一区在线播放| 婷婷开心激情网| 国产日韩在线精品av| 中文av一区| 欧美成人国产精品一区二区| 欧美一级欧美一级在线播放| 成人短视频app| 白白操在线视频| 欧美国产精品劲爆| 成 人 免费 黄 色| 国产精品成人免费视频| 真实国产乱子伦精品一区二区三区| 女尊高h男高潮呻吟| 欧美日韩一区在线观看| 爱草tv视频在线观看992| 这里只有精品66| 久久久久久久综合狠狠综合|