axios 请求拦截器&响应拦截器与router的导航守卫

一、 拦截器介绍

一般在使用axios时,会用到拦截器的功能,一般分为两种:请求拦截器、响应拦截器。
1.请求拦截器
在请求发送前进行必要操作处理,例如添加统一cookie、请求体加验证、设置请求头等,相当于是对每个接口里相同操作的一个封装;

2.响应拦截器
同理,响应拦截器也是如此功能,只是在请求得到响应之后,对响应体的一些处理,通常是数据统一处理等,也常来判断登录失效等。

二、 Axios实例
1.创建axios实例

// 引入axios
import axios from 'axios'
 
// 创建实例
let instance = axios.create({
    baseURL: 'xxxxxxxxxx',
    timeout: 15000  // 毫秒
})

2.baseURL设置:

let baseURL;
if(process.env.NODE_ENV === 'development') {
    baseURL = 'xxx本地环境xxx';
} else if(process.env.NODE_ENV === 'production') {
    baseURL = 'xxx生产环境xxx';
}
 
// 实例
let instance = axios.create({
    baseURL: baseURL,
    ...
})

3.修改实例配置的三种方式
// 第一种:局限性比较大
axios.defaults.timeout = 1000;
axios.defaults.baseURL = ‘xxxxx’;

// 第二种:实例配置

let instance = axios.create({
    baseURL: 'xxxxx',
    timeout: 1000,  // 超时,401
})
// 创建完后修改
instance.defaults.timeout = 3000
 
// 第三种:发起请求时修改配置、
instance.get('/xxx',{
    timeout: 5000
})

这三种修改配置方法的优先级如下:请求配置 > 实例配置 > 全局配置

三、 配置拦截器

// 请求拦截器
instance.interceptors.request.use(req=>{}, err=>{});
// 响应拦截器
instance.interceptors.reponse.use(req=>{}, err=>{});

从上可以看出,instance依然是第二步中创建的实例,然后对其进行拦截,请求用request,响应用reponse,二者都有两个配置项,一个是成功配置,一个是error配置。

1.请求拦截器

// use(两个参数)
axios.interceptors.request.use(req => {
    // 在发送请求前要做的事儿
    ...
    return req
}, err => {
    // 在请求错误时要做的事儿
    ...
    // 该返回的数据则是axios.catch(err)中接收的数据
    return Promise.reject(err)
})

2.响应拦截器

// use(两个参数)
axios.interceptors.reponse.use(res => {
    // 请求成功对响应数据做处理
    ...
    // 该返回的数据则是axios.then(res)中接收的数据
    return res
}, err => {
    // 在请求错误时要做的事儿
    ...
    // 该返回的数据则是axios.catch(err)中接收的数据
    return Promise.reject(err)
})

3.常见错误码处理(error)
axios请求错误时,可在catch里进行错误处理。

axios.get().then().catch(err => {
    // 错误处理
})

但实际开发过程中,一般在请求/响应拦截器中统一做错误处理,有特殊接口的话做单独的catch错误处理

四、 axios请求拦截器的案例
axios请求发送之前,拦截请求,在请求中判断是不是post提交,是就做出处理

import axios from 'axios'
 
// 创建一个axios实例
const axios_instance = axios.create()
//设置axios拦截器: 请求拦截器
axios_instance.interceptors.request.use(config => {
  //得到请求方式和请求体数据
  const {method,data} = config;
  if(method.toLowerCase() == 'post' && typeof data == 'object'){
     config.data = qs.stringify(data)
  }
  config.headers['X-Token'] = getToken()
  return config;
}, err => {
  // 请求未成功发出,如:没有网络...
  return Promise.reject(err)
})
//设置axios拦截器: 响应拦截器
axios_instance.interceptors.response.use(res => {
  // 成功响应的拦截
  const data = res.data;
  const code = data.code;

  if(code == 200  ){
    return data;
  }else{
    return Promise.reject(data);
  }
}, err =>{
  //请求的地址错误 会进入这里
  console.log(err)
  return Promise.reject(err)  
})

导航守卫

import router from '@/router'
import store from '@/store'
import { Message } from 'element-ui'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { getToken } from '@/assets/js/utils/token'

const whiteList = ['/login']

router.beforeEach(async(to, from, next) => {

  NProgress.start()

  const hasToken = getToken()
  if (hasToken) {
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done()
    } else {
      const hasGetUserInfo = store.getters.name
      if (hasGetUserInfo) {
        next()
      } else {
        try {
          await store.dispatch('user/getInfo')
          next()
        } catch (error) {
          console.log(error)
          await store.dispatch('user/resetToken')
          Message.error(error || 'Has Error')
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done()
})
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值