今回は、vue axios がインターフェイスを呼び出すときのリクエスト タイムアウトについて説明します。以下は実際的なケースです。見てみましょう。
Vue2を使用して以来、APIを呼び出すために公式に推奨されているaxiosプラグインを使用していますが、使用中にサーバーまたはネットワークが不安定でパケットがドロップした場合、どのように対処すればよいでしょうか? 。
具体的な理由
最近、サーバー側のデータインターフェイスがPhpによって出力されたAPIを使用しているため、呼び出しプロセス中に暫定ヘッダーが表示されることがあります。

検索エンジンによって与えられた解決策によると、私の問題を解決できません
最近、私はAOPの開発とプログラミングの概念を勉強しています。axios開発手順に記載されている列インターセプター(axios.Interceptors)。このメカニズムにより、コードの結合が減少し、プログラムの再利用性が向上し、開発効率が向上します。
落とし穴のある解決策 1
私の経験は限られており、私にできる唯一のことは、axios リクエストがタイムアウトした後に新しいリクエストを作成することだと思います。 axios の使用手順を確認して、タイムアウト = 6000 を設定してから
1 | axios.defaults.timeout = 6000;
|
ログイン後にコピー
、列インターセプターを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | axios.interceptors.request. use ( function (config) {
return config;
}, function (error) {
return Promise.reject(error);
});
axios.interceptors.response. use ( function (response) {
return response;
}, function (error) {
return Promise.reject(error);
});
|
ログイン後にコピー
この列インターセプターの役割は、リクエストがタイムアウトした場合に列インターセプターが情報を取得できることです。 , そして次のステップに進みます。つまり、再リクエストを使用したいと考えています。
関連するページデータのリクエストは次のとおりです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | this. $axios .get(url, {params:{load: 'noload' }}).then( function (response) {
}). catch (error => {
if (error.response) {
console.log( 'error.response' )
console.log(error.response);
} else if (error.request) {
console.log(error.request)
console.log( 'error.request' )
if (error.request.readyState == 4 && error.request.status == 0){
}
} else {
console.log( 'Error' , error.message);
}
console.log(error.config);
});
|
ログイン後にコピー
タイムアウト後、「Uncaught (in Promise) Error: timeout of xxx ms Overceed」エラーが報告されます。

catchではerror.requestエラーが返されるので、ここでリトライ機能を実行します。 テスト後、タイムアウト再リクエスト機能は実装できますが、 API をリクエストするすべてのページに再リクエストを設定する必要があるため、非常に面倒です。

上記を見てください、私のプロジェクトには数十の.vueファイルがあります。すべてのページにタイムアウトと再リクエスト機能を設定する必要がある場合、私は気が狂ってしまいます。
そして、このメカニズムには重大な問題があります。バグは、要求されたリンクが失敗したり、他の理由で正常にアクセスできない場合に、このメカニズムが失敗することです。設定した 6 秒を待たずに、毎秒数十回リクエストを更新し続けます。これは簡単です。あっという間に146回もサーバーがダウンしてしまいました。下の写真をご覧ください。
落とし穴のある解決策 2
は、タイムアウト後にエラー メッセージがインターセプター axios.interceptors.response にキャプチャされ、error.code = "ECONNABORTED "、特定のリンク
https://github.com/axios/axios/blob/26b06391f831ef98606ec0ed406d2be1742e9850/lib/adapters/xhr.js#L95-L101
1 2 3 4 5 6 7 | request.ontimeout = function handleTimeout() {
reject(createError( 'timeout of ' + config.timeout + 'ms exceeded' , config, 'ECONNABORTED' ,
request));
request = null;
};
|
ログイン後にコピー
つまり、私のグローバルタイムアウト再取得ソリューションは次のようになります。
1 2 3 4 5 6 7 8 9 | axios.interceptors.response. use ( function (response){
....
}, function (error){
var originalRequest = error.config;
if (error.code == 'ECONNABORTED' && error.message.indexOf( 'timeout' )!=-1 && !originalRequest._retry){
originalRequest._retry = true
return axios.request(originalRequest);
}
});
|
ログイン後にコピー
このメソッドは新しいリクエストを実装することもできますが、2 つの問題があります。 1. 再リクエストは 1 回だけであり、再度タイムアウトになると停止し、再度リクエストされません。 2 番目の問題は、 this.$axios.get(url).then
の後の操作など、データ要求を伴う各ページで多くの操作を実行することです。 this.$axios.get(url).then
之后操作。
完美的解决方法
以AOP编程方式,我需要的是一个 超时重新请求的全局功能, 要在axios.Interceptors下功夫,在github的axios的issue找了别人的一些解决方法,终于找到了一个完美解决方案,就是下面这个。
https://github.com/axios/axios/issues/164#issuecomment-327837467
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | axios.defaults.retry = 4;
axios.defaults.retryDelay = 1000;
axios.interceptors.response. use (undefined, function axiosRetryInterceptor(err) {
var config = err.config;
if (!config || !config.retry) return Promise.reject(err);
config.__retryCount = config.__retryCount || 0;
if (config.__retryCount >= config.retry) {
return Promise.reject(err);
}
config.__retryCount += 1;
var backoff = new Promise( function (resolve) {
setTimeout( function () {
resolve();
}, config.retryDelay || 1);
});
return backoff.then( function () {
return axios(config);
});
});
|
ログイン後にコピー
其他的那个几十个.vue页面的 this.$axios
🎜🎜完璧なソリューション🎜🎜🎜🎜 AOPプログラミングで必要なのは、axios.Interceptorsで熱心に取り組む必要があることです。axiosの問題で他の人からいくつかの解決策が見つかりました。 github で、最終的に次のような完璧な解決策が見つかりました。 🎜🎜 https://github.com/axios/axios/issues/164#issuecomment-327837467 🎜
1 2 3 4 5 | import axios from 'axios' ;
npm install axios
bower install axios
|
ログイン後にコピー
ログイン後にコピー
🎜他の数十の .vue ページの
this.$axios
の取得と投稿メソッドは、コードをまったく変更する必要があります。 🎜
在这个过程中,谢谢jooger给予大量的技术支持,这是他的个人信息 https://github.com/jo0ger , 谢谢。
以下是我做的一个试验。。把axios.defaults.retryDelay = 500, 请求 www.facebook.com

如有更好的建议,请告诉我,谢谢。
补充:
axios基本用法
vue更新到2.0之后,作者就宣告不再对vue-resource更新,而是推荐的axios,前一段时间用了一下,现在说一下它的基本用法。
首先就是引入axios,如果你使用es6,只需要安装axios模块之后
1 2 3 4 5 | import axios from 'axios' ;
npm install axios
bower install axios
|
ログイン後にコピー
ログイン後にコピー
当然也可以用script引入
axios提供了一下几种请求方式
1 2 3 4 5 6 7 | axios.request(config)
axios.get(url[, config])
axios. delete (url[, config])
axios.head(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
|
ログイン後にコピー
这里的config是对一些基本信息的配置,比如请求头,baseURL,当然这里提供了一些比较方便配置项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | import Qs from 'qs'
{
url: '/user' ,
method: 'get' ,
baseURL: 'https://some-domain.com/api/' ,
transformRequest: [ function (data) {
data = Qs.stringify({});
return data;
}],
transformResponse: [ function (data) {
return data;
}],
headers: { 'X-Requested-With' : 'XMLHttpRequest' },
params: {
ID: 12345
},
data: {
firstName: 'Fred'
},
timeout: 1000,
responseType: 'json' ,
}
|
ログイン後にコピー
有了配置文件,我们就可以减少很多额外的处理代码也更优美,直接使用
1 2 3 4 5 6 7 8 9 10 11 12 13 | axios.post(url,{},config)
.then( function (res){
console.log(res);
})
. catch ( function (err){
console.log(err);
})
axios.all([get1(), get2()])
.then(axios.spread( function (res1, res2) {
}));
|
ログイン後にコピー
最后还是说一下配置项,上面讲的是额外配置,如果你不想另外写也可以直接配置全局
1 2 3 4 5 6 7 | axios.defaults.baseURL = 'https://api.example.com' ;
axios.defaults.headers.common[ 'Authorization' ] = AUTH_TOKEN;
axios.defaults.headers.post[ 'Content-Type' ] = 'application/x-www-form-urlencoded' ;
var instance = axios.create({
baseURL: 'https://api.example.com'
});
|
ログイン後にコピー
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
webpack+dev+server使用详解
Angular2使用Dom有哪些注意事项
以上がvue axios がインターフェイスを呼び出すときにリクエストがタイムアウトするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。