axios-使用技巧

144 阅读2分钟

取消重复请求

使用情况:当网速太慢,请求速度变慢,但却又进行请求,会浪费性能,所以为了解决这个问题,axios有个属性可以解决。

AbortController

从 v0.22.0 开始,Axios 支持以 fetch API 方式—— AbortController 取消请求:

const controller = new AbortController();
axios.get('/foo/bar', { signal: controller.signal }).then(function(response) {
//... 
});
// 取消请求 
controller.abort()

CancelToken deprecated

您还可以使用 cancel token 取消一个请求。

Axios 的 cancel token API 是基于被撤销 cancelable promises proposal

此 API 从 v0.22.0 开始已被弃用,不应在新项目中使用。

可以使用 CancelToken.source 工厂方法创建一个 cancel token ,如下所示:

const CancelToken = axios.CancelToken;
const source = CancelToken.source(); 
axios.get('/user/12345',{
cancelToken: source.token 
}).catch(function (thrown) { 
if (axios.isCancel(thrown)){
console.log('Request canceled', thrown.message); 
}else { 
// 处理错误 } 
}); 
axios.post('/user/12345', { 
name: 'new name' 
}, { 
cancelToken: source.token 
}) 
// 取消请求(message 参数是可选的) 
source.cancel('Operation canceled by the user.');

也可以在请求拦截器的时候添加

// 请求的间隙
axios.defaults.retryDelay = 1000;
const pending = [];
//取消请求的函数
const removePending = (config) => {
  let pendingIndex = pending.findIndex((v) => {
  //判断config里面的内容是否是上一次请求的接口
    if (
      config.url === v.url &&
      config.method === v.method &&
      JSON.stringify(config.params) === JSON.stringify(v.params) &&
      JSON.stringify(config.body) === JSON.stringify(v.body)
    ) {
      v.controller.abort();
      return true;
    }
    return false;
  });
  if (pendingIndex >= 0) {
    pending.splice(pendingIndex, 1);
  }
};

axios.interceptors.request.use(function (config){
 // 取消重复请求
    removePending(config);
    const controller = new AbortController();
    config.signal = controller.signal;
    config.controller = controller;
    pending.push({ ...config });
    return config;
},
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);

token失效跳转到登录页面

在路由页面定义

//定义一个时间
let time=30000
//router. beforeEach 是全局钩子函数,它是在路由跳转之前所调用的函数,在实际开发中页面进度条的加载、设置页面标题、判断用户是否已经登录过了等等都可以在该函数中执行。
router.beforeEach((to, from, next) => {
  //把转化为字符串的本地取出来 并转换回来
  let token=JSON.parse(localStorage.getItem('token'))
  //如果本地有数据
  if(token){
    //获取当前时间
    let newtime=new Date().getTime()
    // 当前时间减去存储时间是否大于30000毫秒
    if(newtime-token.time>time){
      // 如果大于清楚本地存储并跳转登录
      localStorage.removeItem('token')
      next('/')
    }else{
 
    }
  }else{
    //如果没有数据返回登录页面
    if(to.path=="/"){
      next()
    }else{
      alert('请先登录,在访问其他页面')
      next('/')
    }
  }
})

在axios响应拦截器定义

import router from "@/router";
axios.interceptors.response.use(
  function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    let { data } = response;
    //token失效请求接口的时候的返回值=410000
    if(data.status===410000){
      router.replace('/login')
    }
    return data;
  },
  function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error);
  }
);

接口请求失败重新请求

// 重试次数,共请求2次
axios.defaults.retry = 1;
// 添加请求拦截器
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;

  //打印当前重试次数
  console.log(config.url + " 自动重试第" + config.__retryCount + "次");

  // 创建新的Promise
  var backoff = new Promise(function (resolve) {
    setTimeout(function () {
      resolve();
    }, config.retryDelay || 1);
  });

  // 返回重试请求
  return backoff.then(function () {
    return axios(config);
  });
});