axios的种种操作

167 阅读2分钟

1.axios的二次封装

import axios from 'axios'
import { Message } from 'element-ui'

const http = axios.create({
  baseURL: '/api',  // 在vue.config.js 配置跨域
  timeout: 5000 ,
  withCredentials: false // 表示跨域请求时是否需要使用凭证
})

// 请求拦截器
http.interceptors.request.use(
  config => {

    return config
  },
  error => {
    // do something with request error
    console.log(error) 
    return Promise.reject(error)
  }
)

// 响应拦截器
http.interceptors.response.use(

  response => {
    return response.data
  },
  error => {
    console.log('err' + error)
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default http

复制代码

进行跨域配置

1.我们需要找到vue.config.js文件,编写解决跨域的代码,文件的代码如下

module.exports = {
  lintOnSave: false, //关闭eslint检查
  devServer: {
    open: true,
    // 解决代理跨域问题
    proxy: {
      '/api': {
        target: 'xxx',
        pathRewrite: { '^/api': '' },
        changeOrigin: true   // 允许跨域
      
      }
    }
  }
}
复制代码

2.axios的错误重复请求

import axios from 'axios'

// 重试次数,共请求2次
axios.defaults.retry = 1
// 请求的间隙
axios.defaults.retryDelay = 1000

axios.interceptors.response.use(undefined, function axiosRetryInterceptor(err) {
    // 发送请求后返回错误状态码的那个接口的请求配置,都存在宇err.config里面
    let config = err.config;

    // 如果配置不存在或未设置重试选项,则拒绝
    // 重试请求的次数,如果你设置了1,就请求2次,如果是5,就请求6次
    if (!config || !config.retry) return Promise.reject(err);

    // 设置变量以跟踪重试次数
    config.__retryCount = config.__retryCount || 0;

    // 判断是否超过总重试次数,超过retry设置的次数的时候,就不再重复发起请求了
    if (config.__retryCount >= config.retry) {
        // 返回错误并退出自动重试
        return Promise.reject(err);
    }

    // 增加重试次数
    config.__retryCount += 1;

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

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

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

export default axios;
复制代码

3.axios防止重复请求 优化

import axios from "axios";
const http = axios.create({
baseURL: process.env.VUE_APP_BASE_URL,//公共路径
});
//取消请求 
let httplist = [] 
const removeHttp = config => { 
    let index = httplist.findIndex(v => v.url === config.url && v.method === config.method)
    if (index >= 0) { 
        //取消请求
        httplist[index].controller.abort() 
        //删除当前数据
        httplist.splice(index, 1) 
        } 
      } 
http.interceptors.request.use(
    function (config) { 
        removeHttp(config) 
        //取消操作
        //在push之前遍历数组找到相同的请求取消掉 
        const controller = new AbortController() 
        config.signal = controller.signal //用来取消操作的key 
        config.controller = controller //将控制器绑定到每个请求身上
        httplist.push({ ...config }) //每次的请求加入到数组 
        return config
    },
    function (error) {
        // 对请求错误做些什么
        return Promise.reject(error) 
    } 
) 
// 添加响应拦截器
http.interceptors.response.use( 
    function (response) { 
        // 2xx 范围内的状态码都会触发该函数。
        // 对响应数据做点什么 
        const { data } = response;
        return data;
    }, 
    function (error) { 
        // 超出 2xx 范围的状态码都会触发该函数。
        // 对响应错误做点什么
        return Promise.reject(error);
    } 
);
复制代码

4.token失效返回登录页面

实现方式: 在路由文件router/index.js文件下面的登录路由中添加一个对公的条件,然后在beforeEach钩子函数中添加条件判断条件:

// 登录的路由中添加对公的条件
  {
    path: "/",
    redirect: "/login",
  },{
    path: "/login",
    name: "login",
    component: () => import("../views/login"),
    meta: { isPublic: true },
  },...




// 按照路由是否公开,来处理路由的动作
router.beforeEach((to, from, next) => {
  //如果不是可公开的路由并且当前没有token,那么要跳转到登陆页
  if (!to.meta.isPublic && !sessionStorage.getItem("token")) {
    next("/");
  }
  next();
});