欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript封裝axios的實現(xiàn)詳解

 更新時間:2022年09月01日 15:39:19   作者:搞前端的小菜  
這篇文章主要介紹了JavaScript封裝axios的實現(xiàn),Axios是一個開放源代碼庫,使我們可以輕松地發(fā)出HTTP請求。 實際上,它是通過額外的超能力來fetch

摘要

在vue中,我們調(diào)用接口使用的都是axios,使用之前我們也會進行一定的封裝,然后再進行使用。

在這里,我們主要說一下axios的實現(xiàn)原理,以及如何使用原生的js來自己封裝出一個axios。

這里實現(xiàn)出幾個主要的方法,包括post請求方法,create配置方法,以及攔截器的方法。

1.post方法

在我們寫方法之前,肯定是要先自己寫一個類出來,里面的內(nèi)容先不用寫。

然后再在類的下面寫出post的方法:

function iaxios () {
}
iaxios.prototype.post = function (url, data){
}

OK,現(xiàn)在我們來實現(xiàn)這個方法。

如果我們想用原生的js來實現(xiàn)post請求,我們應該這樣做:

    var xhr = new XMLHttpRequest();
    xhr.open('post', url, true);
    xhr.onreadystatechange = function () {
      if (xhr.readyState == 4) {
        if ((xhr.status == 200 || xhr.status == 304)) {
          resolve(xhr.responseText)
        } else {
          reject(xhr.responseText)
        }
      }
    };
    xhr.send(data)

但是我們直接把這段代碼放進去的話,會有一點問題:

1.官方的axios返回的是一個promise對象

2.官方的axios.post方法傳的data參數(shù)是一個對象,原生的是一個字符串

所以為了解決第一個問題,我們可以在方法內(nèi)返回一個promise對象,而第二個問題可以使用JSON.stringfy()這個方法解決。

iaxios.prototype.post = function (url, data) {
  //返回promise對象
  return new Promise((resolve, reject) => {
    var xhr = new XMLHttpRequest();
    xhr.open('post', url, true);
    xhr.onreadystatechange = function () {
      if (xhr.readyState == 4) {
        if ((xhr.status == 200 || xhr.status == 304)) {
          resolve(xhr.responseText)
        } else {
          reject(xhr.responseText)
        }
      }
    };
    xhr.send(JSON.stringify(data))
  })
}

這樣我們就實現(xiàn)了post的這個方法了。

而對get方法這里就不再寫一遍了(寫的時候主要注意參數(shù)的問題就可以了)。

2.create方法

首先我們知道,axios的create方法主要是對請求頭等參數(shù)的配置,而這個方法同樣也會返回一個axios的實例,這個實例可以繼續(xù)使用post等方法。

所以我們首先想到的是,這個方法應該返回一個實例對象,而這個實例對象下的屬性會根據(jù)傳進來的對象設置。

這里面我只列舉兩個屬性:

iaxios.prototype.create = function (obj) {
  var emaxios = new iaxios()
  emaxios.headers = obj.headers;
  emaxios.baseUrl = obj.baseUrl;
  return emaxios;
}

但是我們調(diào)用完這個create方法后,我們已經(jīng)有了一些配置,如果再調(diào)用post等方法,我們應該是攜帶著這些參數(shù)去調(diào)用psot方法,所以在post方法內(nèi)我們也要修改一下。

我們首先寫一個配置請求頭的方法:

function setHeader (xhr, headers) {
  for (var i in headers) {
    xhr.setRequestHeader(i, headers[i]);
  }
}

然后在post方法內(nèi),在ajax請求發(fā)送之前調(diào)用這個方法就可以了:

    setHeader(xhr, this.headers);

3.攔截器

在axios中,攔截器分兩種,分別是請求攔截和響應攔截。

二者的作用也是相差不多的,一個是希望在請求之前做什么,一個是希望在請求之后做什么。

我們先來寫一下請求攔截(這里面不考慮use):

我們先想一下,interceptors一定是一個對象,并且下面有兩個屬性,分別是request和response。

那么我們就在類里面寫一下:

function iaxios () {
  this.interceptors = {
    request (cb) {
    },
    response (aa) {
    },
  }
}

如果我們想在外邊調(diào)用這個方法,會將一個回調(diào)函數(shù)傳進來,

所以在我們這里我們需要把這個回調(diào)函數(shù)保存下來(考慮到有多個攔截器,所以我們采用數(shù)組保存)。

同時我們也要寫一個data用于存放請求時的數(shù)據(jù)(因為在請求攔截器的回調(diào)函數(shù)中,有一個config參數(shù),它包含著請求的數(shù)據(jù))

function iaxios () {
  //保存攔截器中的回調(diào)函數(shù)
  this.saveRequest = []
  this.saveResponse = []
  //保存請求的數(shù)據(jù)
  this.data = {};
  let _this = this;
  this.interceptors = {
    request (cb) {
      _this.saveRequest.push(cb)
    },
    response (aa) {
      _this.saveResponse.push(aa)
    },
  }
}

現(xiàn)在攔截器的方法已經(jīng)寫好了,我們應該在什么時候調(diào)用呢?

請求攔截一定是在請求發(fā)送之前進行調(diào)用,我們拿post來舉例子:

iaxios.prototype.post = function (url, data) {
  this.data = data;
  let _this = this;
  // this.saveRequest && this.saveRequest(this)
  //請求之前調(diào)用請求攔截的回調(diào)函數(shù)
  if (this.saveRequest) {
    this.saveRequest.forEach(fn => {
      fn(this)
    })
  }

我們只需要在請求之前,把想要傳遞的數(shù)據(jù)copy下來(用于當作參數(shù))。

然后循環(huán)調(diào)用我們保存下來的方法(其實就是調(diào)用的時候傳遞回調(diào)函數(shù))

這樣就能實現(xiàn)請求攔截了。

那么響應攔截一定是在返回響應數(shù)據(jù)之前調(diào)用了:

        if ((xhr.status == 200 || xhr.status == 304)) {
          //用來保存返回的數(shù)據(jù)
          let newRespose = new Object;
          newRespose.data = JSON.parse(xhr.responseText);
          //在返回數(shù)據(jù)之前調(diào)用相應攔截器的回調(diào)函數(shù)
          if (_this.saveResponse) {
            _this.saveResponse.forEach(fn => {
              fn(newRespose)
            })
          }
          resolve(newRespose.data)

這里面我們創(chuàng)建的newRespose也是為了當作參數(shù)傳遞到響應攔截的方法里面。

這樣的話響應攔截器的實現(xiàn)也完成了。

4.代碼

最后再把整體的代碼復制一份:

// const { resolve, reject } = require("core-js/fn/promise")
function iaxios () {
  //保存攔截器中的回調(diào)函數(shù)
  this.saveRequest = []
  this.saveResponse = []
  //保存請求的數(shù)據(jù)
  this.data = {};
  let _this = this;
  this.interceptors = {
    request (cb) {
      _this.saveRequest.push(cb)
    },
    response (aa) {
      _this.saveResponse.push(aa)
    },
  }
}
iaxios.prototype.post = function (url, data) {
  this.data = data;
  let _this = this;
  // this.saveRequest && this.saveRequest(this)
  //請求之前調(diào)用請求攔截的回調(diào)函數(shù)
  if (this.saveRequest) {
    this.saveRequest.forEach(fn => {
      fn(this)
    })
  }
  //返回promise對象
  return new Promise((resolve, reject) => {
    var xhr = new XMLHttpRequest();
    xhr.open('post', url, true);
    //設置請求頭的配置
    setHeader(xhr, this.headers);
    xhr.onreadystatechange = function () {
      if (xhr.readyState == 4) {
        if ((xhr.status == 200 || xhr.status == 304)) {
          //用來保存返回的數(shù)據(jù)
          let newRespose = new Object;
          newRespose.data = JSON.parse(xhr.responseText);
          // _this.saveResponse && _this.saveResponse(newRespose)
          //在返回數(shù)據(jù)之前調(diào)用相應攔截器的回調(diào)函數(shù)
          if (_this.saveResponse) {
            _this.saveResponse.forEach(fn => {
              fn(newRespose)
            })
          }
          resolve(newRespose.data)
        } else {
          reject(xhr.responseText)
        }
      }
    };
    xhr.send(JSON.stringify(data))
  })
}
iaxios.prototype.get = function (url) {
  let _this = this;
  // this.saveRequest && this.saveRequest(this)
  //請求之前調(diào)用請求攔截的回調(diào)函數(shù)
  if (this.saveRequest) {
    this.saveRequest.forEach(fn => {
      fn(this)
    })
  }
  //返回promise對象
  return new Promise((resolve, reject) => {
    var xhr = new XMLHttpRequest();
    xhr.open('get', url, true);
    //設置請求頭的配置
    setHeader(xhr, this.headers);
    xhr.onreadystatechange = function () {
      if (xhr.readyState == 4) {
        if ((xhr.status == 200 || xhr.status == 304)) {
          //用來保存返回的數(shù)據(jù)
          let newRespose = new Object;
          newRespose.data = JSON.parse(xhr.responseText);
          // _this.saveResponse && _this.saveResponse(newRespose)
          //在返回數(shù)據(jù)之前調(diào)用相應攔截器的回調(diào)函數(shù)
          if (_this.saveResponse) {
            _this.saveResponse.forEach(fn => {
              fn(newRespose)
            })
          }
          resolve(newRespose.data)
        } else {
          reject(xhr.responseText)
        }
      }
    };
    xhr.send()
  })
}
//返回一個新的實例并且復制obj的屬性
iaxios.prototype.create = function (obj) {
  var emaxios = new iaxios()
  emaxios.headers = obj.headers;
  emaxios.baseUrl = obj.baseUrl;
  return emaxios;
}
//設置請求頭的方法
function setHeader (xhr, headers) {
  for (var i in headers) {
    xhr.setRequestHeader(i, headers[i]);
  }
}
var taxios = new iaxios();
export {
  taxios
}

到此這篇關于JavaScript封裝axios的實現(xiàn)詳解的文章就介紹到這了,更多相關JS封裝axios內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • bootstrap實現(xiàn)tab選項卡切換

    bootstrap實現(xiàn)tab選項卡切換

    這篇文章主要為大家詳細介紹了bootstrap實現(xiàn)tab選項卡切換,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • JavaScript實現(xiàn)隱藏省略文字效果的方法

    JavaScript實現(xiàn)隱藏省略文字效果的方法

    這篇文章主要介紹了JavaScript實現(xiàn)隱藏省略文字效果的方法,涉及javascript基于事件響應實現(xiàn)頁面字符串元素的獲取、截取、設置等相關操作技巧,需要的朋友可以參考下
    2017-04-04
  • js實現(xiàn)顯示手機號碼效果

    js實現(xiàn)顯示手機號碼效果

    本文主要介紹了js實現(xiàn)顯示手機號碼效果的實例,具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03
  • Nuxt.js中PC與移動端間自動識別跳轉(zhuǎn)

    Nuxt.js中PC與移動端間自動識別跳轉(zhuǎn)

    本文主要介紹了Nuxt.js中PC與移動端間自動識別跳轉(zhuǎn),文中根據(jù)實例編碼詳細介紹的十分詳盡,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • JavaScript設置彈出式獨立窗口頁面和window的方法舉例詳解

    JavaScript設置彈出式獨立窗口頁面和window的方法舉例詳解

    window.open是網(wǎng)頁中經(jīng)常遇到的彈出窗口代碼,不是網(wǎng)絡中比較反感的那類彈出代碼,下面這篇文章主要給大家介紹了關于JavaScript設置彈出式獨立窗口頁面和window的方法,需要的朋友可以參考下
    2024-01-01
  • JS中正則表達式全局匹配模式 /g用法詳解

    JS中正則表達式全局匹配模式 /g用法詳解

    本文章通過實例代碼給大家詳細介紹js中正則表達式的全局匹配模式 /g的用法,需要的朋友參考下
    2017-04-04
  • JS中getElementsByClassName與classList兼容性問題解決方案分析

    JS中getElementsByClassName與classList兼容性問題解決方案分析

    這篇文章主要介紹了JS中getElementsByClassName與classList兼容性問題解決方案,結合實例形式分析了getElementsByClassName與classList的使用方法、原理及兼容性問題的處理技巧,需要的朋友可以參考下
    2019-08-08
  • js返回上一頁并刷新代碼整理

    js返回上一頁并刷新代碼整理

    返回上一頁并刷新在此功能有利于用戶的體驗,是每一個web開發(fā)人員所必備的一項,長話短說,今天介紹實現(xiàn)此功能的一個方法,需要了解的朋友可以參考下
    2012-12-12
  • 怎么在下面的HTML里調(diào)用數(shù)組cs[]的值

    怎么在下面的HTML里調(diào)用數(shù)組cs[]的值

    怎么在下面的HTML里調(diào)用數(shù)組cs[]的值...
    2007-01-01
  • JavaScript實現(xiàn)函數(shù)重載的代碼示例

    JavaScript實現(xiàn)函數(shù)重載的代碼示例

    在JavaScript中并沒有直接支持函數(shù)重載的機制,但是可以通過一些技巧來模擬函數(shù)重載的效果,比如使用參數(shù)判斷,使用默認參數(shù),對象參數(shù),這些方法都可以實現(xiàn)類似函數(shù)重載的效果,所以本文就給大家介紹一下JavaScript如何實現(xiàn)函數(shù)重載,需要的朋友可以參考下
    2023-08-08

最新評論