Vue项目二次封装request并且使用拦截器增加请求头token

vue项目中如果使用到登录注册会用到token,这里需要我们在二次封装的request中设置拦截器,

首先在plugins文件下新建一个reques.js

import axios from 'axios'
import { Message } from 'element-ui'
import store from '@/store'
import router from '@/router/index.js'

var CancelToken = axios.CancelToken
const service = axios.create({
  // baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 15000 // request timeout
})
// request interceptor 请求之前拦截判断,权限等处理
service.interceptors.request.use(
  (config) => {
    // do something before request is sent
    if (!localStorage.getItem('token')) {
      router.replace({
        name: '/loginPage'
      })
    } else {
      config.headers['token'] = localStorage.getItem('token')
    }
    config.cancelToken = new CancelToken(e => {
      store.state.axiosCancel.push(e)
    })
    // if (store.getters.token) {
      // let each request carry token
      // ['X-Token'] is a custom headers key
      // please modify it according to the actual situation
      // config.headers['X-Token'] = getToken()
    // }
    return config
  },
  (error) => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  }
)

// response interceptor
service.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
   */

  /**
   * Determine the request status by custom code
   * Here is just an example
   * You can also judge the status by HTTP Status Code
   */
  (response) => {
    const res = response.data
    if (!res.data) {
      if (res.code === '200') {
        return Promise.reject(new Error('数据异常!'))
        // localStorage.removeItem('token');
      } else {
        return res
      }
    } else if (res.data instanceof Array) {
      if (res.data.length === 0) {
        return Promise.reject(new Error('数据异常!'))
      } else {
        return res
      }
    } else {
      return res
    }
    // var str = JSON.stringify(res)
    // var json = JSON.parse(str)
    // console.log(json)

    // if the custom code is not 20000, it is judged as an error.
    // if (res.code !== 20000 && res.code !== 0) {
    //   // Message({
    //   //   message: res.message || 'Error',
    //   //   type: 'error',
    //   //   duration: 5 * 1000
    //   // })

    //   // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
    //   if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
    //     // to re-login
    //     MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
    //       confirmButtonText: 'Re-Login',
    //       cancelButtonText: 'Cancel',
    //       type: 'warning'
    //     }).then(() => {
    //       store.dispatch('user/resetToken').then(() => {
    //         location.reload()
    //       })
    //     })
    //   }
    //   return Promise.reject(new Error(res.message || 'Error'))
    // } else {
    //  }
  },
  (error) => {
    console.log('err' + error) // for debug
    // Message({
    //   message: error.message,
    //   type: 'error',
    //   duration: 5 * 1000
    // })
    return Promise.reject(error).catch(err => {
      console.log(err)
    })
    // return Promise.reject(error)
  }
)

export default service

具体我们看一下拦截器的内容,这里我们每次请求时都给请求设置一个拦截器,拦截器主要判断我们 localStorage.token是否存在,如果存在就给请求设置一个请求头,如果没有token就回到登陆界面,注意请求还是出去了,还是能.then得到结果。

在真实项目中,当路由已经跳转,而上一页的请求还在pending状态,如果数据量小还好,数据量大时,跳到新页面,旧的请求依旧没有停止,这将会十分损耗性能,这时我们应该先取消掉之前还没有获得相应的请求,再跳转页面。所以这里我们用到了CancelToken,通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token,在vuex里写一个全局axiosCancel的空数组,用来装我们的cancel函数,每次请求时都将cancel函数推入的axiosCancel数组。

然后我们在路由守卫里添加一个清空cancel的方法,这样就实现了每次切换页面时都会清空padding状态的请求,减少性能消耗

router.beforeEach((to, from, next) => {
   //中断请求
    store.state.axiosCancel.forEach(item=> {
        item()
  }) 
//清空数组
   store.state.axiosCancel = []
})

封装好请求后,我们新建一个api文件夹,这里存放各种接口,我这里就举两个post和get方法的例子供参考

import request from '@/plugins/axios'
// 根据指定条件数据
export function getUsersByConditions(params) {
    return request({
      url: '/019/user/getUsersByConditions',
      method: 'get',
      params: params
    })
}
// 修改用户数据
export function saveOrUpdateUser(data) {
  return request({
    url: '/019/user/saveOrUpdateUser',
    method: 'post',
   data
  })
}

你可能感兴趣的:(vue.js,javascript,ecmascript)