前端封装request文件(请求拦截器,响应拦截器)

代码如下,里面都有备注

//导入axios 
import axios from 'axios'
//引入errorCode 
import errorCode from '@/utils/errorCode'
// 是否显示重新登录
export let isRelogin = { show: false };

// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: xxxxxx,//这里配置你的公共路径
  // 超时
  timeout: 60000
})

// request拦截器
service.interceptors.request.use(config=>{
  // 是否需要设置 token
  const isToken = (config.headers || {}).isToken === false
  // 是否需要防止数据重复提交
  const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
  if (getToken() && !isToken) {
    config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
  }
// get请求映射params参数
  if (config.method === 'get' && config.params) {
    let url = config.url + '?' + tansParams(config.params);
    url = url.slice(0, -1);
    config.params = {};
    config.url = url;
  }
//↑↑↑↑代码解释
//首先,代码检查了请求的method属性是否为get,并且还有config.params属性是否存在,如果条件成立,则会执行以下操作:
//创建一个url变量,将config.url和查询参数config.params拼接成一个完整的URL字符串。
//tansParams是一个函数,它将config.params转换为查询字符串的形式。
//url字符串的最后一个字符是不必要的,因此使用slice(0, -1)将其去除。
//将config.params清空,以避免在请求中重复包含参数。
//最后,将config.url属性更新为新的URL。


 if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
    const requestObj = {
      url: config.url,
      data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
      time: new Date().getTime()
    }
    const sessionObj = cache.session.getJSON('sessionObj')
    if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
      cache.session.setJSON('sessionObj', requestObj)
    } else {
      const s_url = sessionObj.url;                // 请求地址
      const s_data = sessionObj.data;              // 请求数据
      const s_time = sessionObj.time;              // 请求时间
      const interval = 1000;                       // 间隔时间(ms),小于此时间视为重复提交
      if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
        const message = '数据正在处理,请勿重复提交';
        console.warn(`[${s_url}]: ` + message)
        return Promise.reject(new Error(message))
      } else {
        cache.session.setJSON('sessionObj', requestObj)
      }
    }
  }

//↑↑↑↑代码解释
//这段代码用于防止重复提交数据,首先,代码检查了是否存在isRepeatSubmit变量,并且检查了请求的方法是否为post或put。如果条件成立,则会执行以下操作:
//创建一个requestObj对象,其中包含请求的URL、数据和时间戳。
//使用cache.session存储此对象,以便进行后续的比较。
//已存储的请求对象sessionObj是否存在。
//如果sessionObj不存在,则调用cache.session.setJSON存储requestObj中的数据。
//如果sessionObj存在,则检查现有请求与先前存储的请求之间的时间间隔是否小于1000ms(即是否重复提交)。如果是,则返回错误信息并拒绝Promise;否则,存储新的请求对象并继续执行

//这段代码的作用是避免用户在短时间内重复提交相同的表单数据,从而导致后端处理异常或重复执行服务端操作。该代码通过比较日志中已存在的请求对象和当前请求对象,并检查它们之间的时间间隔,来判断当前请求是否是重复的。如果请求被视为重复,则返回一个错误信息并拒绝Promise,否则存储当前请求对象并继续执行

return config

},error => {
    console.log(error)
    Promise.reject(error)
})


// 响应拦截器
service.interceptors.response.use(res=>{
 // 未设置状态码则默认成功状态
    const code = res.data.code || 200;
// 获取错误信息
    const msg = errorCode[code] || res.data.msg || errorCode['default']
 // 二进制数据则直接返回
    if(res.request.responseType ===  'blob' || res.request.responseType ===  'arraybuffer'){
      return res.data
    }
 if (code === 401) {
      if (!isRelogin.show) {
        isRelogin.show = true;
        ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
          confirmButtonText: '重新登录',
          cancelButtonText: '取消',
          type: 'warning'
        }
      ).then(() => {
        isRelogin.show = false;
       // 在这里调用退出登录的方法,使其重定向到登录页面

      }).catch(() => {
        isRelogin.show = false;
      });
    }
 return Promise.reject('无效的会话,或者会话已过期,请重新登录。')

 } else if (code === 500) {
      ElMessage({
        message: msg,
        type: 'error'
      })
      return Promise.reject(new Error(msg))
    } else if (code !== 200) {
      ElNotification.error({
        title: msg
      })
      return Promise.reject('error')
    } else {
      return  Promise.resolve(res.data)
    }

},error => {
    console.log('err' + error)
    let { message } = error;
    if (message == "Network Error") {
      message = "后端接口连接异常";
    }
    else if (message.includes("timeout")) {
      message = "系统接口请求超时";
    }
    else if (message.includes("Request failed with status code")) {
      message = "系统接口" + message.substr(message.length - 3) + "异常";
    }
    ElMessage({
      message: message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  })


export default service


引入的errorCode 文件代码如下

export default {
  '401': '认证失败,无法访问系统资源',
  '403': '当前操作没有权限',
  '404': '访问资源不存在',
  'default': '系统未知错误,请反馈给管理员'
}

其中ElMessage提示消息是引入了element ui框架。

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

励志做个全栈开发的小男生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值