前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >axios请求超时,设置重新请求的完美解决方法

axios请求超时,设置重新请求的完美解决方法

作者头像
IMWeb前端团队
发布于 2019-12-03 08:29:55
发布于 2019-12-03 08:29:55
5.7K00
代码可运行
举报
文章被收录于专栏:IMWeb前端团队IMWeb前端团队
运行总次数:0
代码可运行

本文作者:IMWeb ssttm169 原文出处:IMWeb社区 未经同意,禁止转载

自从使用Vue2之后,就使用官方推荐的axios的插件来调用API,在使用过程中,如果服务器或者网络不稳定掉包了, 你们该如何处理呢? 下面我给你们分享一下我的经历。

具体原因

最近公司在做一个项目, 服务端数据接口用的是Php输出的API, 有时候在调用的过程中会失败, 在谷歌浏览器里边显示Provisional headers are shown。

按照搜索引擎给出来的解决方案,解决不了我的问题.

最近在研究AOP这个开发编程的概念,axios开发说明里边提到的栏截器(axios.Interceptors)应该是这种机制,降低代码耦合度,提高程序的可重用性,同时提高了开发的效率。

带坑的解决方案一

我的经验有限,觉得唯一能做的,就是axios请求超时之后做一个重新请求。通过研究 axios的使用说明,给它设置一个timeout = 6000

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
axios.defaults.timeout =  6000;

然后加一个栏截器.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 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);
});

这个栏截器作用是 如果在请求超时之后,栏截器可以捕抓到信息,然后再进行下一步操作,也就是我想要用 重新请求。

这里是相关的页面数据请求。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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);
});

超时之后, 报出 Uncaught (in promise) Error: timeout of xxx ms exceeded的错误。

在 catch那里,它返回的是error.request错误,所以就在这里做 retry的功能, 经过测试是可以实现重新请求的功功能, 虽然能够实现 超时重新请求的功能,但很麻烦,需要每一个请API的页面里边要设置重新请求。

看上面,我这个项目有几十个.vue 文件,如果每个页面都要去设置超时重新请求的功能,那我要疯掉的.

而且这个机制还有一个严重的bug,就是被请求的链接失效或其他原因造成无法正常访问的时候,这个机制失效了,它不会等待我设定的6秒,而且一直在刷,一秒种请求几十次,很容易就把服务器搞垮了,请看下图, 一眨眼的功能,它就请求了146次。

带坑的解决方案二

研究了axios的源代码,超时后, 会在拦截器那里 axios.interceptors.response 捕抓到错误信息, 且 error.code = "ECONNABORTED",具体链接

https://github.com/axios/axios/blob/26b06391f831ef98606ec0ed406d2be1742e9850/lib/adapters/xhr.js#L95-L101

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    // Handle timeout
    request.ontimeout = function handleTimeout() {
      reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED',
        request));

      // Clean up request
      request = null;
    };

所以,我的全局超时重新获取的解决方案这样的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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);
    }
});

这个方法,也可以实现得新请求,但有两个问题,1是它只重新请求1次,如果再超时的话,它就停止了,不会再请求。第2个问题是,我在每个有数据请求的页面那里,做了许多操作,比如 this.$axios.get(url).then之后操作。

完美的解决方法

以AOP编程方式,我需要的是一个 超时重新请求的全局功能, 要在axios.Interceptors下功夫,在github的axios的issue找了别人的一些解决方法,终于找到了一个完美解决方案,就是下面这个。

https://github.com/axios/axios/issues/164#issuecomment-327837467

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//在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);
    });
});

其他的那个几十个.vue页面的 this.$axios的get 和post 的方法根本就不需要去修改它们的代码。

在这个过程中,谢谢jooger给予大量的技术支持,这是他的个人信息 https://github.com/jo0ger , 谢谢。

以下是我做的一个试验。。把axios.defaults.retryDelay = 500, 请求 www.facebook.com

如有更好的建议,请告诉我,谢谢。

github源代码

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-06-04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
关于批量请求refresh token的解决方案
// for multiple requests let isRefreshing = false; let failedQueue = []; const processQueue = (error, token = null) => { failedQueue.forEach(prom => { if (error) { prom.reject(error); } else { prom.resolve(token); } }) fa
lilugirl
2019/11/21
1K0
axios笔记(二) 深入了解axios
那么,axios.create(config)肯定得有它的过人之处,否则,早就会被淘汰掉了。
赤蓝紫
2023/01/05
3.1K0
axios笔记(二)    深入了解axios
react 封装 请求拦截器
世间万物皆对象
2024/03/20
1930
axios拦截器
Axios的请求拦截器允许您在发送请求之前对其进行拦截和修改。您可以使用axios.interceptors.request对象来添加和移除请求拦截器。以下是请求拦截器的使用方法:
堕落飞鸟
2023/05/19
9840
Java Vue 前后端跨域解决方案
事情起因,因为公司目前有些东西很每天录数据很麻烦,所以打算自己给公司写一个库存管理的项目,可是在写好接口后,前端封装完axios后请求接口时出现了岔子,居然 跨域 了!!!!😭
白衣少年
2024/06/06
1520
Java Vue 前后端跨域解决方案
77.9K Star 的 Axios 项目如何优雅实现请求重试
项目中,经常会有很多用户的网络抽风或者各种原因造成偶发性的网络异常请求错误,如果没有重试机制,有时候体验就比较糟糕。这个时候实现网络错误请求错误重试也能比较好的解决这种偶发场景。
ACK
2020/11/24
3.5K0
axios
axios 是 Vue 推荐的一款基于 Promise 的 AJAX 组件。所以我们在使用 Vue 进行项目开发时一般都使用这个库来执行 AJAX 请求。 发送请求 axios.get(url[,config]):发送GET请求 axios.post(url,data):发送POST请求 axios.put(url,data[,config]):发送PUT请求 axios.delete(url[,config]):发送DELETE请求 axios.options(url[,config]):发送OPT
一个淡定的打工菜鸟
2018/09/06
1.5K0
axios
axios 基本使用 增删改查,get查,post增,put改,delete查 <body> <button id="1">点我</button> <button id="2">点我2</button> <button id="3">点我3</button> <button id="5">点我5</button> <script> var btn = document.getElementById('1') var btn2 =
ymktchic
2022/01/18
1.5K0
axios
vue3 + vite 进行axios请求封装及接口API的统一管理
这篇文章跟vite关系不大,下篇写环境变量配置的时候就是vite相关了,今天这里主要讲一下在vue3中axios的实战用法以及Api的统一管理,手把手教学望各位在这里能碰擦出灵感的火花,放飞五彩的思绪。
inline705
2021/12/09
18.1K0
vue3 + vite 进行axios请求封装及接口API的统一管理
Axios 功能扩展之 axios-retry 源码阅读笔记
通过对 axios-retry 这一周下载量 100w+ 的三方库来学习下其功能设计,工具库项目的发包策略,并借此抛砖引玉,以提升我们的编码设计能力!
小东同学
2022/07/29
1.5K0
Axios 功能扩展之 axios-retry 源码阅读笔记
详细自定义封装Axios请求库,你还不会二次封装吗?
使用Vue的时候,Axios几乎已经是必用的请求库了,但是为了更方便搭配项目使用,很多开发者会选择二次封装,Vue3就很多人选择二次封装elementPlus,那其实,Axios我们也是经常会去封装的。
JanYork_简昀
2022/09/19
6.1K0
详细自定义封装Axios请求库,你还不会二次封装吗?
Vue3中使用axios
axios是一个基于Promise的HTTP请求库,它可以在浏览器和Node.js中使用。axios的功能非常请打,支持Promise API、可以拦截请求和响应、可以转换请求和响应数据、支持取消请求、可以自动转换JSON数据等。
九仞山
2023/10/14
1.8K0
Vue3中使用axios
mpvue中配置axios使用
mpvue 小程序使用 axios配置 import axios from 'axios' import qs from 'qs' // 时间戳 const NewTimeStamp = new Date().getTime(); axios.defaults.timeout = 30000; axios.defaults.headers.post[ 'Content-Type' ] = 'application/x-www-form-urlencoded;charset=UTF-8'; axios.d
yangdongnan
2019/03/28
1.5K0
【收藏干货】axios配置大全
//当实例创建时候修改配置 instance.defaults.headers.common["Authorization"] = AUTH_TOKEN; 3、 配置中的有优先级
super.x
2019/04/12
1K0
Axios入门与源码解析
(1) 需求: 项目中有部分接口需要的配置与另一部分接口需要的配置不太一样, 如何处理
鱼找水需要时间
2023/02/16
3K0
Axios入门与源码解析
axios详解以及完整封装方法
Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。
HelloWorldZ
2024/03/20
9.5K0
Vue笔记:封装 axios 为插件使用
自从Vue2.0推荐大家使用 axios 开始,axios 被越来越多的人所了解。使用axios发起一个请求对大家来说是比较简单的事情,但是axios没有进行封装复用,项目越来越大,引起的代码冗余。就会非常麻烦的一件事。所以本文会详细的跟大家介绍,如何封装请求,并且在项目组件中复用请求。有需要的朋友可以做一下参考。
朝雨忆轻尘
2019/06/19
2K0
Vue笔记:封装 axios 为插件使用
面试官:Vue项目中有封装过axios吗?怎么封装的?
基于 XMLHttpRequest 服务来执行 HTTP 请求,支持丰富的配置,支持 Promise,支持浏览器端和 Node.js 端。自Vue2.0起,尤大宣布取消对 vue-resource 的官方推荐,转而推荐 axios。现在 axios 已经成为大部分 Vue 开发者的首选
@超人
2021/02/26
2K0
一文掌握Axios:前后端数据交互竟如此简单
你写了一个很棒的前端项目,一切顺利运行,直到你需要和后端进行数据交互时。此时,前端的页面和后端的服务器就像是两个相隔千里的邻居,彼此之间的沟通仿佛隔着一道厚墙。你想要的数据请求和响应总是有点“卡壳”,问题重重。这时,Axios 就成了你解决问题的利器。是不是心里在想,怎么就这么巧,今天的文章正好讲这个?
方才编程_公众号同名
2024/12/10
2770
一文掌握Axios:前后端数据交互竟如此简单
axios请求二次封装,兼容typescript
适合初学者配置使用,只封装了get和post其他类似patch、put和axios.all()的方法得自己动手了,如果遇到项目有多个baseURL的这套封装就显得很不灵活,但一般是不会遇到的,这套简单的封装总的来说够用了,且非常实用。 新建https.ts复制下面代码进去引用即可,如果是js版本的把url:any, param:any后面的:any去掉。 import axios from 'axios' import qs from 'qs' axios.defaults.timeout = 5000;
骤雨重山
2022/01/17
8230
相关推荐
关于批量请求refresh token的解决方案
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文