vue中axios请求拦截详解 | 8月更文挑战

342 阅读1分钟

这是我参与8月更文挑战的第31天,活动详情查看:8月更文挑战

一、定义请求axios公共文件,并在main.js中引入

main.js
import axios from './utils/requestAxios';Vue.prototype.$axios = axios;

在utils文件夹中创建requestAxios.js文件,不用请求拦截是可以直接引入axios,不引入这个自定义拦截的文件就行。

二、创建只有接口名的变量文件

和requestAxios.js同级,constant.js

这里定义了两个请求地址,提示:请求地址最好只有域名,如果后期服务增加,后面admin或者user都不是的话,下面就要做很多判断,代码会很冗余!

// 测试环境const BASE_URL = 'https://aaa.com.cn:8080/admin/api';const BASE_URL_MEMBER = 'https://aaa.com.cn:8080/user/api'export default {  BASE_URL,  BASE_URL_MEMBER}

三、完善requestAxios.js实现请求拦截

import axios from 'axios'
import { Loading, Message } from 'element-ui'
import CONSTANT from './constant'
const service = axios.create({  
  baseURL: CONSTANT.BASE_URL,  
  timeout: 30000
})
let loadingInstance = nullservice.interceptors.request.use(config => {    
  //判断如果是会员就修改调接口前缀    
  if (config.url.indexOf('/story') != -1) {      
    config.baseURL = CONSTANT.BASE_URL_MEMBER    
  }    
  config.headers.Authorization = localStorage.getItem('TOKEN');   
  loadingInstance = Loading.service({      
    lock: true,      
    text: '加载中……',      
    spinner: 'el-icon-loading',      
    background: 'rgba(0, 0, 0, 0.7)'    
  })    
  return config; 
},  error => {    
  return Promise.reject(error)  
})
service.interceptors.response.use(response => {
  //响应拦截    
  loadingInstance.close();
  const { data } = response.data;  
  return data;
}, error => {    
  // 请求错误处理    
  loadingInstance.close();    
  switch (error.response.status) {      
    case 401:// token 过期        
      Message.error(`登录超时,请重新登录`);
      localStorage.clear();
      window.location.reload();
      break;      
    case 500:          
      Message.error(`${error.response.data.message}`);
      break      
    default:        
      Message.error(`请求超时`);        
      break    
  }    
  return Promise.reject(error);
})
// 400 错误单独处理
service.interceptors.response.use(
  data => data,
  error => {
    const { status, data } = error.response;
    if (status === 400) {
      Message.error(`${data.message}`);
      loadingInstance.close();
    }
    return Promise.reject(error)
  }
)
export default service
  1. 引入axios,并引入定义变量的文件constant.js
  2. 定义service,使用axios.create创建一个服务,定义请求地址和超时时间,我这里定义的是五分钟后请求未响应自动提示请求超时。
  3. 定义elementui提供的loading加载框
  4. 设置axios定义的服务请求配置,Tips:注意我在constant.js中不小心定义的请求接口地址太长,后期如果接口域名不动,但是服务名变了,例如baseUrl不是admin/api而是/baseAdmin/api,项目开发一半了总不能全局再替换,这样可能会有bug,如果时间精力多修改是最好。我这里写了解决办法,就是判断请求地址如果包含story就请求另一个地址,这样不会出错,也可以全局解决,感觉这里体会到请求拦截的好处了。
  5. 如果有token,就放在请求头中返回出去
  6. 设置请求响应,关闭loading加载框
  7. 响应结果错误处理,这里可以根据不同需求进行处理,401超时,500报错,404跳转不同页面等
  8. 最后通过promise返回给请求的地方。

四、请求模拟

//get请求
this.$axios.get(`/userList?pageSize=1&pageSize=2`).then(res => {        console.log(res);})
//post请求
this.$axios.post(`/story/addUserInfo`,{
    "username": '小鲸鱼',
    "age": "18"
}).then(res => {
  _this.$message({
    message: '请求成功!',
    type: 'success'
  });
})

这里get请求和post请求都模拟了一下和axios自带的一样,只不过自己拦截请求了一下,更适配自己的项目,其中第二个post请求中含story就会调用定义的第二个请求地址,这样就能避免一开始定义太长的请求地址后期不适配的问题了。