ネイティブ js を使用して axios をカプセル化する (詳細な説明)

まとめ

vue では、axios を使用してインターフェイスを呼び出します。また、使用する前に特定のカプセル化を実行してから使用します。

ここでは、主に axios の実装原理と、ネイティブ js を使用して axios をカプセル化する方法について説明します。

ここでは、ポストリクエスト メソッド、構成の作成メソッド、インターセプターメソッドなど、いくつかの主要なメソッドが実装されています

1.投稿方法

メソッドを書く前に、まず自分でクラスを書く必要があり、内部の内容を書く必要はありません。
次に、クラスの下に post メソッドを記述します。

function iaxios () {
    
    

}

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

}

では、このメソッドを実装しましょう。

ネイティブ js を使用して投稿リクエストを実装する場合は、次のようにする必要があります。

    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 パラメーターはオブジェクトであり、元のパラメーターは文字列です。

したがって、最初の問題を解決するために、メソッドで promise オブジェクトを返すことができ、2 つ目の問題は 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))
  })
}

このようにして、投稿のメソッドを実装しました。
getメソッドについては、ここでは書きません(パラメータに注意して書いてください)。

2.メソッドを作成する

まず第一に、axios の create メソッドは主にリクエストの最初のパラメーターを構成することであり、このメソッドは axios のインスタンスも返し、post などのメソッドを引き続き使用できることを知っています。

したがって、最初に考えたのは、このメソッドはインスタンス オブジェクトを返す必要があり、このインスタンス オブジェクトのプロパティは、渡されたオブジェクトに従って設定されるということです。

ここでは、2 つの属性のみをリストします。

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

ただし、create メソッドを呼び出した後、既にいくつかの構成が存在します. post および他のメソッドを再度呼び出す場合は、これらのパラメーターを使用して psot メソッドを呼び出す必要があるため、post メソッドでも変更する必要があります.

最初にリクエストヘッダーを設定するメソッドを書きます:

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

次に、post メソッドで、ajax リクエストが送信される前にこのメソッドを呼び出すだけです。

    setHeader(xhr, this.headers);

3.インターセプター

axios には、リクエスト インターセプトとレスポンス インターセプトという 2 種類のインターセプターがあります。

2 つの機能は似ており、1 つはリクエストの前に実行したいこと、もう 1 つはリクエストの後に実行したいことです。

最初にリクエストの傍受について書きましょう (使用はここでは考慮されません)。

最初に考えてみましょう。インターセプターはオブジェクトでなければなりません。以下に、リクエストとレスポンスという 2 つの属性があります。

次に、クラスに次のように記述します。

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

    },
  }
}

このメソッドを外部で呼び出したい場合は、コールバック関数が渡されるので、
ここではこのコールバック関数を保存する必要があります (インターセプターが複数あることを考慮して、配列を使用して保存します)。

同時に、リクエストのデータを格納するためのデータも書き込む必要があります (リクエスト インターセプターのコールバック関数には、リクエストされたデータを含む構成パラメーターがあるため)

function iaxios () {
    
    
  //保存拦截器中的回调函数
  this.saveRequest = []
  this.saveResponse = []
  //保存请求的数据
  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)
  //请求之前调用请求拦截的回调函数
  if (this.saveRequest) {
    
    
    this.saveRequest.forEach(fn => {
    
    
      fn(this)
    })
  }

リクエストの前に、渡したいデータ (パラメーターとして使用) をコピーするだけです。
次に、保存したメソッドをループで呼び出します (実際には、呼び出し時にコールバック関数を渡すためです)。

これにより、リクエストのインターセプトが有効になります。

次に、応答データを返す前に応答インターセプトを呼び出す必要があります。

        if ((xhr.status == 200 || xhr.status == 304)) {
    
    
          //用来保存返回的数据
          let newRespose = new Object;
          newRespose.data = JSON.parse(xhr.responseText);
          //在返回数据之前调用相应拦截器的回调函数
          if (_this.saveResponse) {
    
    
            _this.saveResponse.forEach(fn => {
    
    
              fn(newRespose)
            })
          }
          resolve(newRespose.data)

ここで作成した newRespose も、パラメーターとして応答傍受メソッドに渡されます。

このようにして、応答インターセプターの実装も完了します。

4. コード

最後に、コード全体をもう一度コピーします。

// const { resolve, reject } = require("core-js/fn/promise")

function iaxios () {
    
    
  //保存拦截器中的回调函数
  this.saveRequest = []
  this.saveResponse = []
  //保存请求的数据
  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)
  //请求之前调用请求拦截的回调函数
  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)) {
    
    
          //用来保存返回的数据
          let newRespose = new Object;
          newRespose.data = JSON.parse(xhr.responseText);
          // _this.saveResponse && _this.saveResponse(newRespose)
          //在返回数据之前调用相应拦截器的回调函数
          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)
  //请求之前调用请求拦截的回调函数
  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)) {
    
    
          //用来保存返回的数据
          let newRespose = new Object;
          newRespose.data = JSON.parse(xhr.responseText);
          // _this.saveResponse && _this.saveResponse(newRespose)
          //在返回数据之前调用相应拦截器的回调函数
          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
}

Supongo que te gusta

Origin blog.csdn.net/weixin_46726346/article/details/118970057
Recomendado
Clasificación