axios的二次封装

  • 1、请求拦截(往请求头部加公共部分参数)
  • 2、响应拦截(正常访问、登录掉线、异常等处理)
  • 3、错误统一处理
  • 4、可取消网络请求(如:切换页面,取消原页面上未完成的网络请求)

一、axios封装如下:

// request.js文件
import axios from 'axios'
import qs from 'qs'
import router from '../router'

// 定义全局变量clearRequest,在route.js中要用到
export const clearRequest = {
  source: {
    token: null,
    cancel: null
  }
}
const cancelToken = axios.CancelToken
const source = cancelToken.source()

const service = axios.create({
  // process.env.NODE_ENV === 'development' 来判断是否开发环境
  // baseURL: 'https://www.xyz.com/api/',
  baseURL: process.env.NODE_ENV === 'development' ? '/api' : '/',
  timeout: 12000
})

// 请求拦截器
service.interceptors.request.use(
  config => {
    if (config.method === 'post' || config.method === 'put') {
      config.data = qs.stringify(config.data)
    }
    // 头部加入公共信息
    if (!config.headers.Authorization) {
      config.headers['Authorization'] = `Bearer ${getLocalStorage(
        'token'
      ) || ''}`
      config.headers['OS'] = 'android' // android端
      config.headers['Source'] = '1' // 渠道包编号
    }
    // 在发送请求设置cancel token
    config.cancelToken = clearRequest.source.token // 这句很重要
    return config
  },
  error => {
    console.log(error)
    return Promise.reject(error)
  }
)

service.interceptors.response.use(
  response => {
    // 此次可以统一处理返回逻辑,如:关闭请求网络页面上的加载弹框等
    if (response.status === 200) {
      return response.data
    } else if (response.status === 400) { // 未登录
      removeLocalStorage('token') // 清除原来的token的值
      const curRouter = window.location.hash.substring(1) // 截取hash的路由
	  router.replace({ path: '/login', query: { redirect: curRouter } })
    } else {
      Promise.reject(response)
    }
  },
  error => {
    let errMsg = '请重试~'
    if (error.message && error.message.indexOf('timeout') > -1) {
      errMsg = '网络请求超时,请重试~'
    } else if (error.message && error.message.indexOf('Network') > -1) {
      errMsg = '网络异常,请重试~'
    }
    if (error.message && error.message.indexOf('Cancel') < 0) { // cancel的取消请求不作处理
      // Dialog.alert({ // error.message
      //   title: '提示',
      //   message: errMsg
      // })
    }
    console.log(error + errMsg)
    return Promise.reject(error)
  }
)

const post = (url, data, config = {}) => service.post(url, data,
  {
    ...config, cancelToken: source.token // 这句很重要
  })

const get = (url, params, config = {}) =>
  service.get(url, {
    params,
    ...config,
    cancelToken: source.token // 这句很重要
  })

export default {
  install (Vue) {
    Vue.prototype.$reqGet = get
    Vue.prototype.$reqPost = post
  }
}

二、取消未完成的网络请求

使用场景:切换页面,取消原页面上未完成的网络请求
router路由beforeEach 加入如下代码即可:

import { clearRequest } from '@utils/request'

// 切换路由时清空上个路由未完成的所有请求
const CancelToken = axios.CancelToken
clearRequest.source.cancel && clearRequest.source.cancel()
clearRequest.source = CancelToken.source()

你可能感兴趣的:(vue)