まとめ
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
}