今回は、vue axios リクエストタイムアウトに対処する方法と、vue axios リクエストタイムアウトに対処する際の注意事項を紹介します。実際のケースを見てみましょう。
Vue2を使用して以来、APIを呼び出すために公式に推奨されているaxiosプラグインを使用していますが、使用中にサーバーまたはネットワークが不安定でパケットがドロップした場合、どのように対処すればよいでしょうか? 。
具体的な理由
最近、サーバー側のデータインターフェイスがPhpによって出力されたAPIを使用しているため、呼び出しプロセス中に暫定ヘッダーが表示されることがあります。
検索エンジンで与えられた解決策に従っても、私の問題は解決できません。
最近、AOPの開発とプログラミングの概念と、axiosで言及されているカラムインターセプター(axios.Interceptors)を勉強しています。開発指示 コードの結合を減らし、プログラムの再利用性を向上させ、開発効率を向上させるのは、このメカニズムであるはずです。
落とし穴のある解決策 1
私の経験は限られており、私にできる唯一のことは、axios リクエストがタイムアウトした後に新しいリクエストを作成することだと思います。 axios の使用方法を勉強して、タイムアウト = 6000 に設定してから、カラム インターセプターを追加します。
axios.defaults.timeout = 6000;
このカラム インターセプターの役割は、リクエストがタイムアウトした後に情報を取得し、次のステップに進むことです。 、つまり、再リクエストを使用したいと考えています。
関連するページデータのリクエストは次のとおりです。
// Add a request interceptor axios.interceptors.request.use(function (config) { // Do something before request is sent return config; }, function (error) { // Do something with request error return Promise.reject(error); }); // Add a response interceptor axios.interceptors.response.use(function (response) { // Do something with response data return response; }, function (error) { // Do something with response error return Promise.reject(error); });
タイムアウト後、「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
this.$axios.get(url, {params:{load:'noload'}}).then(function (response) { //dosomething(); }).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); });
つまり、私のグローバルタイムアウト再取得ソリューションは次のようになります。
// Handle timeout request.ontimeout = function handleTimeout() { reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED', request)); // Clean up request request = null; };
このメソッドは新しいリクエストを実装することもできますが、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
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); } });
其他的那个几十个.vue页面的 this.$axios
//在main.js设置全局的请求次数,请求的间隙 axios.defaults.retry = 4; axios.defaults.retryDelay = 1000; axios.interceptors.response.use(undefined, function axiosRetryInterceptor(err) { var config = err.config; // If config does not exist or the retry option is not set, reject if(!config || !config.retry) return Promise.reject(err); // Set the variable for keeping track of the retry count config.retryCount = config.retryCount || 0; // Check if we've maxed out the total number of retries if(config.retryCount >= config.retry) { // Reject with the error return Promise.reject(err); } // Increase the retry count config.retryCount += 1; // Create new promise to handle exponential backoff var backoff = new Promise(function(resolve) { setTimeout(function() { resolve(); }, config.retryDelay || 1); }); // Return the promise in which recalls axios to retry the request return backoff.then(function() { return axios(config); }); });
this.$axios
の取得と投稿メソッドは、コードをまったく変更する必要があります。 🎜在这个过程中,谢谢jooger给予大量的技术支持,这是他的个人信息 https://github.com/jo0ger , 谢谢。
以下是我做的一个试验。。把axios.defaults.retryDelay = 500, 请求 www.facebook.com
如有更好的建议,请告诉我,谢谢。
补充:
axios基本用法
vue更新到2.0之后,作者就宣告不再对vue-resource更新,而是推荐的axios,前一段时间用了一下,现在说一下它的基本用法。
首先就是引入axios,如果你使用es6,只需要安装axios模块之后
import axios from 'axios'; //安装方法 npm install axios //或 bower install axios
当然也可以用script引入
axios提供了一下几种请求方式
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,当然这里提供了一些比较方便配置项
//config import Qs from 'qs' { //请求的接口,在请求的时候,如axios.get(url,config);这里的url会覆盖掉config中的url url: '/user', // 请求方法同上 method: 'get', // default // 基础url前缀 baseURL: 'https://some-domain.com/api/', transformRequest: [function (data) { // 这里可以在发送请求之前对请求数据做处理,比如form-data格式化等,这里可以使用开头引入的Qs(这个模块在安装axios的时候就已经安装了,不需要另外安装) data = Qs.stringify({}); return data; }], transformResponse: [function (data) { // 这里提前处理返回的数据 return data; }], // 请求头信息 headers: {'X-Requested-With': 'XMLHttpRequest'}, //parameter参数 params: { ID: 12345 }, //post参数,使用axios.post(url,{},config);如果没有额外的也必须要用一个空对象,否则会报错 data: { firstName: 'Fred' }, //设置超时时间 timeout: 1000, //返回数据类型 responseType: 'json', // default }
有了配置文件,我们就可以减少很多额外的处理代码也更优美,直接使用
axios.post(url,{},config) .then(function(res){ console.log(res); }) .catch(function(err){ console.log(err); }) //axios请求返回的也是一个promise,跟踪错误只需要在最后加一个catch就可以了。 //下面是关于同时发起多个请求时的处理 axios.all([get1(), get2()]) .then(axios.spread(function (res1, res2) { // 只有两个请求都完成才会成功,否则会被catch捕获 }));
最后还是说一下配置项,上面讲的是额外配置,如果你不想另外写也可以直接配置全局
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' });
本文只是介绍基本的用法,详细看官方文档https://github.com/axios
我写的两个例子:
使用vue2.0+mintUI+axios+vue-router: https://github.com/Stevenzwzhai/vue-mobile-application
使用vue2.0+elementUI+axios+vue-router: https://github.com/Stevenzwzhai/vue2.0-elementUI-axios-vueRouter, 之前由于没做后端接口,所以运行没数据,现在加了mockjs来返回一些数据,以便于参考。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上がvue axios リクエストのタイムアウトを処理する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。