最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

摘要

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

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

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

1.post方法

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

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

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

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

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

    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)

但是我們直接把這段代碼放進(jìn)去的話,會(huì)有一點(diǎn)問題:

1.官方的axios返回的是一個(gè)promise對(duì)象

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

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

iaxios.prototype.post = function (url, data) {
  //返回promise對(duì)象
  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))
  })
}

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

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

2.create方法

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

所以我們首先想到的是,這個(gè)方法應(yīng)該返回一個(gè)實(shí)例對(duì)象,而這個(gè)實(shí)例對(duì)象下的屬性會(huì)根據(jù)傳進(jìn)來的對(duì)象設(shè)置。

這里面我只列舉兩個(gè)屬性:

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

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

我們首先寫一個(gè)配置請(qǐng)求頭的方法:

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

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

    setHeader(xhr, this.headers);

3.攔截器

在axios中,攔截器分兩種,分別是請(qǐng)求攔截和響應(yīng)攔截。

二者的作用也是相差不多的,一個(gè)是希望在請(qǐng)求之前做什么,一個(gè)是希望在請(qǐng)求之后做什么。

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

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

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

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

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

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

同時(shí)我們也要寫一個(gè)data用于存放請(qǐng)求時(shí)的數(shù)據(jù)(因?yàn)樵谡?qǐng)求攔截器的回調(diào)函數(shù)中,有一個(gè)config參數(shù),它包含著請(qǐng)求的數(shù)據(jù))

function iaxios () {
  //保存攔截器中的回調(diào)函數(shù)
  this.saveRequest = []
  this.saveResponse = []
  //保存請(qǐng)求的數(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)寫好了,我們應(yīng)該在什么時(shí)候調(diào)用呢?

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

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

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

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

這樣就能實(shí)現(xiàn)請(qǐng)求攔截了。

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

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

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

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

4.代碼

最后再把整體的代碼復(fù)制一份:

// const { resolve, reject } = require("core-js/fn/promise")
function iaxios () {
  //保存攔截器中的回調(diào)函數(shù)
  this.saveRequest = []
  this.saveResponse = []
  //保存請(qǐng)求的數(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)
  //請(qǐng)求之前調(diào)用請(qǐng)求攔截的回調(diào)函數(shù)
  if (this.saveRequest) {
    this.saveRequest.forEach(fn => {
      fn(this)
    })
  }
  //返回promise對(duì)象
  return new Promise((resolve, reject) => {
    var xhr = new XMLHttpRequest();
    xhr.open('post', url, true);
    //設(shè)置請(qǐng)求頭的配置
    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)
          //在返回?cái)?shù)據(jù)之前調(diào)用相應(yīng)攔截器的回調(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)
  //請(qǐng)求之前調(diào)用請(qǐng)求攔截的回調(diào)函數(shù)
  if (this.saveRequest) {
    this.saveRequest.forEach(fn => {
      fn(this)
    })
  }
  //返回promise對(duì)象
  return new Promise((resolve, reject) => {
    var xhr = new XMLHttpRequest();
    xhr.open('get', url, true);
    //設(shè)置請(qǐng)求頭的配置
    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)
          //在返回?cái)?shù)據(jù)之前調(diào)用相應(yīng)攔截器的回調(diào)函數(shù)
          if (_this.saveResponse) {
            _this.saveResponse.forEach(fn => {
              fn(newRespose)
            })
          }
          resolve(newRespose.data)
        } else {
          reject(xhr.responseText)
        }
      }
    };
    xhr.send()
  })
}
//返回一個(gè)新的實(shí)例并且復(fù)制obj的屬性
iaxios.prototype.create = function (obj) {
  var emaxios = new iaxios()
  emaxios.headers = obj.headers;
  emaxios.baseUrl = obj.baseUrl;
  return emaxios;
}
//設(shè)置請(qǐng)求頭的方法
function setHeader (xhr, headers) {
  for (var i in headers) {
    xhr.setRequestHeader(i, headers[i]);
  }
}
var taxios = new iaxios();
export {
  taxios
}

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

相關(guān)文章

  • sso跨域?qū)慶ookie的一段js腳本(推薦)

    sso跨域?qū)慶ookie的一段js腳本(推薦)

    下面小編就為大家?guī)硪黄猻so跨域?qū)慶ookie的一段js腳本(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-05-05
  • 關(guān)于axios返回空對(duì)象的問題解決

    關(guān)于axios返回空對(duì)象的問題解決

    這篇文章主要給大家介紹了關(guān)于axios返回空對(duì)象的問題解決方法,文中介紹的非常詳細(xì),相信對(duì)大家學(xué)習(xí)或者使用axios具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。
    2017-04-04
  • JavaScript刪除數(shù)組元素的方法

    JavaScript刪除數(shù)組元素的方法

    這篇文章主要介紹了JavaScript刪除數(shù)組元素的方法,實(shí)例分析了javascript中delete函數(shù)的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-03-03
  • webpack@v4升級(jí)踩坑(小結(jié))

    webpack@v4升級(jí)踩坑(小結(jié))

    這篇文章主要介紹了webpack@v4升級(jí)踩坑(小結(jié)),之前就嘗試了升級(jí),由于部分插件的原因,未能成功,今天就來試一下在我的項(xiàng)目中升級(jí)會(huì)遇到哪些坑。感興趣的小伙伴們可以參考一下
    2018-10-10
  • JS連連看源碼完美注釋版(推薦)

    JS連連看源碼完美注釋版(推薦)

    連連看最難的部分應(yīng)該是路徑搜索,即鼠標(biāo)點(diǎn)的兩點(diǎn)之間看有無可通的路徑。 看過有人寫的遞歸寫法,心里癢癢,就捉摸了一下,發(fā)現(xiàn)不用遞歸的情況下難度也不大
    2013-12-12
  • 多次注冊(cè)事件會(huì)導(dǎo)致一個(gè)事件被觸發(fā)多次的解決方法

    多次注冊(cè)事件會(huì)導(dǎo)致一個(gè)事件被觸發(fā)多次的解決方法

    一個(gè)JavaScript邏輯,會(huì)自動(dòng)綁定函數(shù)到按鈕的click事件,但是這段代碼會(huì)反復(fù)注冊(cè)事件,具體的解決方法如下,感興趣的朋友可以參考下
    2013-08-08
  • 淺析javaScript中的淺拷貝和深拷貝

    淺析javaScript中的淺拷貝和深拷貝

    本篇文章主要介紹了淺析javaScript中的淺拷貝和深拷貝,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-02-02
  • silverlight線程與基于事件驅(qū)動(dòng)javascript引擎(實(shí)現(xiàn)軌跡回放功能)

    silverlight線程與基于事件驅(qū)動(dòng)javascript引擎(實(shí)現(xiàn)軌跡回放功能)

    前一段時(shí)間一直在重構(gòu)工作站軌跡回放功能,一開始我覺得很簡(jiǎn)單,但是后面引發(fā)了一系列奇怪的問題,讓我很疼,所以不得不寫個(gè)總結(jié)加深記憶,
    2011-08-08
  • js的event詳解。

    js的event詳解。

    js的event詳解。...
    2006-09-09
  • layui動(dòng)態(tài)設(shè)置單選按鈕選中效果實(shí)例

    layui動(dòng)態(tài)設(shè)置單選按鈕選中效果實(shí)例

    最近在使用layui前端框架,在使用單選按鈕、下拉菜單select、checkbox等控件的時(shí)候,往往遇到一些初始化的東西,下面這篇文章主要給大家介紹了關(guān)于layui動(dòng)態(tài)設(shè)置單選按鈕選中效果的相關(guān)資料,需要的朋友可以參考下
    2023-06-06

最新評(píng)論

班戈县| 徐汇区| 吉安县| 宜都市| 道孚县| 德昌县| 衡阳县| 黑河市| 和林格尔县| 桃园市| 邵阳县| 禄丰县| 安庆市| 北辰区| 安泽县| 洛阳市| 田林县| 东丽区| 西峡县| 宣威市| 隆德县| 孝感市| 辰溪县| 湾仔区| 丽江市| 岳阳县| 怀化市| 永登县| 沅江市| 南溪县| 墨竹工卡县| 淮安市| 兴海县| 得荣县| 满洲里市| 新田县| 铜陵市| 乾安县| 孙吴县| 阿拉善右旗| 汉源县|