资讯专栏INFORMATION COLUMN

axios基于常见业务场景的二次封装(更新)

dailybird / 313人阅读

摘要:时隔一年再次更新下根据项目下常见业务场景对的二次封装功能实现兼容浏览器避免缓存减少或更新重复请求接口域名使用环境变量全局状态可关闭的全局错误提醒可开启携带全局分页参数拦截器请求拦截器请求开始请求出错响应拦截器请求结束请求错误处理网络请求中,

时隔一年再次更新下根据vue项目下常见业务场景对axios的二次封装

功能实现:
1.兼容ie浏览器避免缓存
2.减少或更新重复请求
3.接口域名使用环境变量
4.全局loading状态
5.可关闭的全局错误提醒
6.可开启携带全局分页参数
7...

拦截器
/**
 * 请求拦截器
 * @param  {} requestStart 请求开始
 */
service.interceptors.request.use(
  config => {
    requestStart({ config });
    return config;
  },
  error => {
    Message.error("请求出错");
    Promise.reject(error);
  }
);
/**
 * 响应拦截器
 * @param  {} requestEnd 1.请求结束
 * @param  {} responseResolve 2.请求错误处理
 */
service.interceptors.response.use(
  response => {
    const { status, data, config } = response;
    requestEnd({ config, data });
    return responseResolve({ status, data, config });
  },
  error => {
    if (axios.isCancel(error)) {
      Message.warning("网络请求中,请不要重复操作!");
    } else {
      const { response } = error;
      Message.error({
        dangerouslyUseHTMLString: true,
        message: `

请求接口: ${ response.config.url }

请求方法 : ${ response.config.method }

响应状态 : ${response.status}

响应信息 : ${ response.statusText }

` }); } store.commit("setLoading", false); store.commit("setPageTotal", 0); return Promise.reject(error); } );
请求开始

处理请求头

处理请求参数

处理重复请求

/**
 * 请求开始&&loading=true
 * @param  {} requestHeaders 请求头
 * @param  {} requestParams 请求参数
 * @param  {} removePending 重复请求
 */
const requestStart = ({ config } = {}) => {
  requestHeaders({ config });
  requestParams({ config });
  removePending({ config });
  addPending({ config });
  store.commit("setLoading", true);
};
请求响应

全局错误提醒,在需要前端自定义提醒的场景下可关闭

/**
 * @param  {} {status HTTP状态码
 * @param  {} data 响应体
 * @param  {} config}={} AxiosRequestConfig
 */
const responseResolve = ({ status, data, config } = {}) => {
  const { code, text } = data;
  if (status === 200) {
    switch (code) {
      case 200:
        return Promise.resolve(data);
      case 900401:
        Message.error(text || "登录超时,请重新登录!");
        window.location.href = process.env.VUE_APP_AUTH_URL;
        return Promise.reject(data);
      default:
        //可配置错误提醒
        if (!config.headers["hide-message"]) {
          Message.error(text || "操作失败!");
        }
        return Promise.reject(data);
    }
  } else {
    Message.error(text || "操作失败!");
    store.commit("setLoading", false);
    return Promise.reject(data);
  }
};
请求结束

处理重复请求

处理分页

处理loading状态

/**
 * 请求结束&&loading=false
 * @param  {} {config}={} AxiosRequestConfig
 * @param  {} {config}={} response body
 */
const requestEnd = ({ config, data } = {}) => {
  removePending({ config });
  store.commit("setLoading", false);
  //配置分页
  if (config.headers.pagination) {
    const { data: content } = data;
    if (content) {
      store.commit("setPageTotal", content.total);
    }
  }
};
以下为具体功能实现 请求头预处理

时间戳:避免ie内核浏览器缓存

token

/**
 * 请求头预处理
 * @param  {} {config} AxiosRequestConfig
 */
const requestHeaders = ({ config }) => {
  //1.时间戳
  const timestamp = new Date().getTime();
  config.headers.timestamp = timestamp;
  //2.token
  const token = sessionStorage.getItem("token");
  if (token) {
    config.headers.token = token;
  }
};
请求参数预处理

可配置的全局分页参数,提供给需要用到全局分页组件的列表请求使用

/**
 * 请求参数预处理
 * @param  {} {config}={} AxiosRequestConfig
 */
const requestParams = ({ config } = {}) => {
  //配置分页
  if (config.headers.pagination) {
    const { pageNum, pageSize } = store.getters.getPagination;
    config.data = Object.assign({}, config.data, {
      pageNum,
      pageSize
    });
  }
};
处理重复请求

此处根据需要可以改为取消上一次的请求

/**
 * 处理重复请求
 * @param  {} {config}={} AxiosRequestConfig
 */
const addPending = ({ config }) => {
  const url =
    config.url + "&" + config.method + "&" + qs.stringify(config.data);
  config.cancelToken = new cancelToken(cancel => {
    if (!pending.some(item => item.url === url)) {
      pending.push({
        url,
        cancel
      });
    }
  });
};
const removePending = ({ config }) => {
  const url =
    config.url + "&" + config.method + "&" + qs.stringify(config.data);
  pending.forEach((item, index) => {
    if (item.url === url) {
      item.cancel("取消重复请求:" + config.url);
      pending.splice(index, 1);
    }
  });
};
完整代码
import { Message } from "element-ui";
import axios from "axios";
import store from "../store/index";
const qs = require("qs");

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 100000
});

const pending = [];
const cancelToken = axios.CancelToken;

/**
 * 处理重复请求
 * @param  {} {config}={} AxiosRequestConfig
 */
const addPending = ({ config }) => {
  const url =
    config.url + "&" + config.method + "&" + qs.stringify(config.data);
  config.cancelToken = new cancelToken(cancel => {
    if (!pending.some(item => item.url === url)) {
      pending.push({
        url,
        cancel
      });
    }
  });
};
const removePending = ({ config }) => {
  const url =
    config.url + "&" + config.method + "&" + qs.stringify(config.data);
  pending.forEach((item, index) => {
    if (item.url === url) {
      item.cancel("取消重复请求:" + config.url);
      pending.splice(index, 1);
    }
  });
};
/**
 * 请求头预处理
 * @param  {} {config} AxiosRequestConfig
 */
const requestHeaders = ({ config }) => {
  //1.时间戳
  const timestamp = new Date().getTime();
  config.headers.timestamp = timestamp;
  //2.token
  const token = sessionStorage.getItem("token");
  if (token) {
    config.headers.token = token;
  }
};
/**
 * 请求参数预处理
 * @param  {} {config}={} AxiosRequestConfig
 */
const requestParams = ({ config } = {}) => {
  //配置分页
  if (config.headers.pagination) {
    const { pageNum, pageSize } = store.getters.getPagination;
    config.data = Object.assign({}, config.data, {
      pageNum,
      pageSize
    });
  }
};
/**
 * 请求开始&&loading=true
 * @param  {} requestHeaders 1.配置请求头
 * @param  {} requestParams 2.配置请求体
 * @param  {} removePending 3.处理重复请求
 */
const requestStart = ({ config } = {}) => {
  requestHeaders({ config });
  requestParams({ config });
  removePending({ config });
  addPending({ config });
  store.commit("setLoading", true);
};
/**
 * 请求结束&&loading=false
 * @param  {} {config}={} AxiosRequestConfig
 * @param  {} {config}={} response body
 */
const requestEnd = ({ config, data } = {}) => {
  removePending({ config });
  store.commit("setLoading", false);
  //配置分页
  if (config.headers.pagination) {
    const { data: content } = data;
    if (content) {
      store.commit("setPageTotal", content.total);
    }
  }
};
/**
 * @param  {} {status HTTP状态码
 * @param  {} data 响应体
 * @param  {} config}={} AxiosRequestConfig
 */
const responseResolve = ({ status, data, config } = {}) => {
  const { code, text } = data;
  if (status === 200) {
    switch (code) {
      case 200:
        return Promise.resolve(data);
      case 900401:
        Message.error(text || "登录超时,请重新登录!");
        window.location.href = process.env.VUE_APP_AUTH_URL;
        return Promise.reject(data);
      default:
        //可配置错误提醒
        if (!config.headers["hide-message"]) {
          Message.error(text || "操作失败!");
        }
        return Promise.reject(data);
    }
  } else {
    Message.error(text || "操作失败!");
    store.commit("setLoading", false);
    return Promise.reject(data);
  }
};
/**
 * 请求拦截器
 * @param  {} requestStart 请求开始
 */
service.interceptors.request.use(
  config => {
    requestStart({ config });
    return config;
  },
  error => {
    Message.error("请求出错");
    Promise.reject(error);
  }
);
/**
 * 响应拦截器
 * @param  {} requestEnd 1.请求结束
 * @param  {} responseResolve 2.请求错误处理
 */
service.interceptors.response.use(
  response => {
    const { status, data, config } = response;
    requestEnd({ config, data });
    return responseResolve({ status, data, config });
  },
  error => {
    if (axios.isCancel(error)) {
      Message.warning("网络请求中,请不要重复操作!");
    } else {
      const { response } = error;
      Message.error({
        dangerouslyUseHTMLString: true,
        message: `

请求接口: ${ response.config.url }

请求方法 : ${ response.config.method }

响应状态 : ${response.status}

响应信息 : ${ response.statusText }

` }); } store.commit("setLoading", false); store.commit("setPageTotal", 0); return Promise.reject(error); } ); export default service;

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106002.html

相关文章

  • axios基于常见业务场景二次封装

    摘要:是一个基于的库,可以用在浏览器和中。我在最近的几个项目中都有使用,并基于根据常见的业务场景封装了一个通用的服务。业务场景全局请求配置。请求携带,权限错误统一管理。 axios axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。在前端框架中的应用也是特别广泛,不管是vue还是react,都有很多项目用axios作为网络请求库。我在最近的几个项...

    JasinYip 评论0 收藏0
  • axios 二次封装(拦截重复请求、异常统一处理)

    摘要:拦截重复请求如何标识每个请求下面函数,通过一个请求参数中的请求传递参数或请求传递参数来表示每一个请求。 一直想封装一下 axios, 可以方便项目中使用,今天有时间,就好好研究了一下。 源码: // util/axios.js import axios from axios const pending = {} const CancelToken = axios.CancelTok...

    luzhuqun 评论0 收藏0
  • 如何构建通用存储中间层

    摘要:并且数据同步后默认会保存下来,这样下次再请求时存储层中就有数据了。以下参数会传到中这么一来,存储层就和接口层对接起来了。五支持永久保存在某些场景下,可能不方便写过期时间,这时默认可以传递,标记该数据永不过期。 零、问题的由来 开门见山地说,这篇文章【又】是一篇安利软文~,安利的对象就是 tua-storage。 顾名思义,这就是一款存储数据的工具。 用 tua-storage 好处大大...

    hersion 评论0 收藏0
  • axios入门实践

    摘要:使用了拦截器处理相关问题,这样就不再需要使用来做错误的处理。万恶的拦截器一些处理无论是对成功的处理还是对失败的处理,如果拦截器不抛出错误,那么终将还会执行里面处理请求成功的函数,即使你返回。 一 前言 本文适合刚接触axios或者使用过几次的同学来分享交流一些入门经验,本文同样适用熟悉axios的同学来作为参考手册。默认你已经看过axios的相关文档:axios文档 GitHub,通过...

    kamushin233 评论0 收藏0
  • 前端基本功-常见概念(一)

    摘要:前端基本功常见概念一点这里前端基本功常见概念二点这里前端基本功常见概念三点这里什么是原型链当一个引用类型继承另一个引用类型的属性和方法时候就会产生一个原型链。函数式编程是声明式而不是命令式,并且应用程序状态通过纯函数流转。 前端基本功-常见概念(一) 点这里前端基本功-常见概念(二) 点这里前端基本功-常见概念(三) 点这里 1.什么是原型链 当一个引用类型继承另一个引用类型的属性和方...

    bladefury 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<