axios请求拦截封装

axios是目前前端最常用的api请求库,这次就结合自己的使用经验分享一下的axios的封装。

官方文档:传送门

一、js封装

request.js:

/**
 * 接口请求基础封装
 */
import axios from 'axios'
import { objToUrlParams } from './tools'

// 创建axios实例
const service = axios.create()

// 定义额外配置
let configMore

/**
 * 数据请求 配置项
 * @params {object} data 传参数据
 * @params {boolean} codeList 可选,控制自行处理接口响应异常的code码列表,默认为空数组
 * ......
 */
function request (config) {
  // 获取额外配置参数
  const { codeList } = config
  configMore = {
    codeList: codeList || []
  }
  // 额外的公共参数(根据公司情况自行调整)
  const reqDataBase = {
    token: '',
    version: '',
  }
  // 合并公共参数
  config.data = {
    ...reqDataBase,
    ...config.data
  }
  return service(config)
}

// 请求拦截
service.interceptors.request.use(
  config => {
    // 超时时间
    config.timeout = config.timeout || 30000
    
    // baseURL
    if (!config.baseURL.match(/^http/)) {
      // baseURL即公共部分的接口,我这里是/api/api
      const baseUrlOrigin = config.baseURL || '/api/api'
      // 这里的/proxy是接口代理的标识,用于拦截请求代理转发,解决跨域问题
      config.baseURL = '/proxy' + baseUrlOrigin
    }
    
    // 数据传参使用表单形式
    config.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'
    // 如果数据传参使用json形式,就改用下面一行
    // config.headers['Content-Type'] = 'application/json; charset=utf-8'
    
    // 请求方法,默认post
    config.method = config.method || 'post'
    
    // 请求参数,这里做了处理,无论是post请求还是get请求都可以统一使用data字段配置请求数据
    if (config.method === 'post') {
      config.data = config.data || {}
      // 数据格式转换
      config.transformRequest = [data => data && objToUrlParams(data)]
      // 如果数据传参使用json形式,就改用下面一行
      // config.transformRequest = [data => data && JSON.stringify(data)]
    } else if (config.method === 'get') {
      // get请求。将data数据转为params数据
      config.params = config.data || config.params || {}
    }
    
    return config
  },
  err => {
    Promise.reject(err)
  }
)

// 响应拦截
service.interceptors.response.use(
  response => {
    const res = response.data
    /**
     * 自行控制返回数据
     */
    if (configMore.codeList.length > 0) {
      const myCodeList = configMore.codeList.map(v => (v + ''))
      if (myCodeList.includes(res.code + '')) {
        // 如果接口返回的code码在配置的codeList列表中,就直接返回数据,在接口调用处自行处理,方便DIY
        return res
      }
    }
    /**
     * 默认自动控制返回数据
     */
    // code为0,正常返回数据
    if (res.code + '' === '0') {
      return res
    }
    // code不为0,不符合预期,输出错误提示,res.error_msg为接口返回的错误信息,根据公司接口情况自行替换相应的字段
    console.log(res.error_msg)
    // code为-1,未登录或登录过期,跳转登录页
    if (res.code + '' === '-1') {
      // ...这里写跳转登录页的逻辑
    }
    // 抛出错误
    return Promise.reject(res)
  },
  err => {
    // 输出错误信息
    console.log('Err:' + err.message)
    return Promise.reject(err)
  }
)

export default request

用到的工具 tools.js:

/**
 * 判断是否是NaN
 * @param {any} val 任意数据类型的数据
 * @return {boolean}
 */
export function judgeNaN (val) {
  return (typeof val) === 'number' && window.isNaN(val)
}

/**
 * 对象参数序列化(过滤undefined和NaN,自动encode)
 * @param {object} obj 对象参数
 * @return {string} a=1&b=2&c=3
 */
export function objToUrlParams (obj) {
  let str = ''
  Object.keys(obj).forEach(v => {
    const val = obj[v]
    if (val !== undefined && !judgeNaN(val)) {
      str += `${encodeURIComponent(v)}=${encodeURIComponent(val)}&`
    }
  })
  return str.slice(0, -1)
}
  • 个人觉得没必要再划分成axios.get和axios.post之类的方法,直接通过method参数指定请求方式就行了。
  • 由于axios的get请求参数只能通过params来传递数据、post请求只能通过data来传递,所以我做了处理,统一通过data传递,在内部封装时再自动进行转换。
  • 从axios的v0.19.0版本开始,axios的config不允许传递非官方支持的配置字段,所以我这里又包装了一层函数request来接受自定义的外部配置,通过外部作用域的configMore变量存储一些非官方支持的配置数据,然后在拦截器里面使用。
  • 像接口code码的分类和判断以及代理标识等等不同公司环境可能不一样,不过都是大同小异,自行替换即可。
  • 其实axios的封装是和公司前后端环境紧密关联的,所以没有一个绝对合适的js封装,我这里也是提供一些较为通用的配置参考。

二、使用示例

api.js

import request from './request'

export function getUserInfo (data) {
  return request({
    method: 'get',
    url: '/app/getInfo',
    data
  })
}

export function getIndexData (data) {
  return request({
    method: 'post',
    url: '/app/getIndex',
    data,
    codeList: [1000, 1100]
  })
}
  • 建议把所有api请求封装在一起,如上api.js,在页面里再引用api.js里的方法调用。
  • 如有必要,可以将request.js作为基础封装,再基于此做几个二次封装来使用,便于不同类型接口的划分。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值