# 拦截器

# 自定义拦截器

自定义拦截器配置路径为src/biz/axios/modules。在本目录下,可分模块创建不同的拦截器。

  1. modules目录下可分模块创建不同的拦截器,如department.jsmessage.js(文件名任意,但必须确保以.js结尾)。

  2. 请求成功拦截器必须命名为requestSuccessHandler,返回值必须为return config。请求失败拦截器必须命名为requestFailHandler,返回值必须为return Promise.reject(error)

  3. 响应成功拦截器必须命名为responseSuccessHandler,返回值必须为return response。响应失败拦截器必须命名为responseFailHandler,返回值必须为return Promise.reject(error)

  4. src/biz/axios/index.js文件中遍历src/biz/axios/modules目录下的所有js文件,并将其导出。

以下为示例代码src/biz/axios/modules

import { Message } from 'hosui'

// 请求成功时
const requestSuccessHandler = function (config) {
  // 在请求头添加参数
  config.headers['TEST'] = 'test'
  return config
}

// 请求失败时
const requestFailHandler = function (error) {
  return Promise.reject(error)
}

// 响应成功时
const responseSuccessHandler = function (response) {
  // 如果响应结果为false,则弹出错误信息提示
  if (!response.data.success) {
    Message.error(response.data.msg)
  }
  return response
}

// 响应失败时
const responseFailHandler = function (error) {
  return Promise.reject(error)
}

export default {
  requestSuccessHandler,
  requestFailHandler,
  responseSuccessHandler,
  responseFailHandler
}

以下为示例代码src/biz/axios/index.js

// 遍历modules下的所有js文件
const files = require.context('./modules', false, /\.js$/)

// 将遍历的数据push到数组中,并导出
const handlers = files.keys().reduce((prev, curr) => {
  prev.push(files(curr).default)
  return prev
}, [])

export default handlers

# 拦截器

拦截器配置路径为src/sys/hos-app-base/axios/interceptors.js

  1. 在本文件中可配置拦截器属性,如在请求头添加token或IP地址等。也可以在获取到响应数据时,根据不同的状态码,执行相应的方法。

  2. 可在function(err){}函数中,定义对请求或响应出错时的处理方法。

  3. 在本文件中可以引入biz文件夹下自定义的拦截器,并在initInterceptors方法中使用。

以下为示例代码

// 引入biz下的自定义拦截器
import handlers from '@/axios'

export class Interceptors {
  // 定义constructor
  constructor(instance) {
    this.instance = instance
    // 初始化拦截器
    this.initInterceptors()
  }
  // 定义get方法
  getInterceptors() {
    return this.instance
  }
  // 定义initInterceptors方法,在此方法中配置拦截器属性,并且引入biz中自定义的拦截器
  initInterceptors() {
    // biz下自定义的请求拦截器
    handlers.forEach((handler) => {
      const { requestSuccessHandler, requestFailHandler } = handler
      if (requestSuccessHandler || requestFailHandler) {
        this.instance.interceptors.request.use(requestSuccessHandler, requestFailHandler)
      }
    })
    
    // 请求拦截器
    this.instance.interceptors.request.use(
      function (config) {
        // 配置请求白名单
        if (requestWhiteList.includes(config.url)) {
          return config
        }
        // 在发送请求之前做些什么,比如:
        config.withCredentials = true
        // 放入访问令牌
        config.headers.common[ACCESS_TOKEN] = getToken()
        if (getToken()) {
          config.headers[ACCESS_TOKEN] = getToken()
        }
      },
      function (error) {
        // 对请求错误做些什么
        return Promise.reject(error)
      }
    )
    
    // biz下自定义的响应拦截器
    handlers.forEach((handler) => {
      const { responseSuccessHandler, responseFailHandler } = handler
      if (responseSuccessHandler || responseFailHandler) {
        this.instance.interceptors.response.use(responseSuccessHandler, responseFailHandler)
      }
    })
    
    // 响应拦截器
    this.instance.interceptors.response.use(
      function (response) {
        // 对响应数据做点什么
        const config = response.config
        // 如果返回4001错误,表示token失效,需要调用刷新token重新获取token
        if (response.data.code === "4001") {
          ......
        }
        // 返回response.data,避免写多个data属性
        return response.data
      },
      function (error) {
        // 对响应错误做些什么
        return Promise.reject(error)
      }
    )
  }
}

响应拦截器对返回数据做了处理,仅返回 http response 中的 data 部分。

配置参照 拦截器 (opens new window)