在Vue项目中对Axios进行二次封装


1.前言

Web开发中,我们最常用的HTTP库就是Axios了,它的底层基于Ajax进行封装,在浏览器端和服务端都可以使用。如果大家对一些API不是很熟悉可以参考官方地址,或者中文社区。虽然现在网上已经有很多基于Axios封装的文章了,但是不妨碍我来接受社区大佬的“棒打”。

2.涉及到的业务场景

  • 多环境:开发、测试、生产环境。
  • 统一错误处理:401、404、500等错误。
  • 断网、请求超时处理。
  • 请求取消/请求拦截:防止重复请求发送到服务端,造成服务端压力。
  • 请求权限:某些接口必须要有登录状态才可以访问。

当然涉及到的场景肯定不会只有这些,实际需要根据业务场景进行更好地配置。

3.如何封装

这里为了方便,我使用了ES6中的Class特性来抽象出一个HttpRequest“类”(JS没有真正的类),它的属性有:

  • baseURL:当前请求的根路径
  • pending: 一个对象,它使用请求API的URL来作为key来存储cancelToken

方法有:

  • getDefaultConfig: 存放默认配置
  • createAxiosInstance: 创建Axios实例
  • interceptors: 配置拦截器
  • cancelKeyManager: cancelKey管理器
  • handleRequestCancel: 处理请求拦截和请求取消
  • removeRequest: 移除请求
  • mergeOptions: 工具函数,合并对象
  • get: get请求方法
  • post: post请求方法

接下来我们开始封装吧~

3.1 统一baseURL管理

其实这一块有很多方法来设置baseURL,比如在process.env定义NODE_ENV,使用webpack.DefinePlugin设置运行时的全局变量(这一部分Vue CLI 已经内置了),也可以使用Vue中的.env.[mode]文件来设置(具体可以参考这里)。

我选择是前一种,在src目录下创建一个config文件夹存放项目运行时所需要的配置(编译时的配置在vue.config.js配置)。

src/config/index.js

export default {
   
  baseURL: {
   
    dev: 'http://localhost:3000',
    test: 'http://ip1:port1',
    prod: 'http://ip2:port2'
  }
}

这样我们只需要通过process.env.NODE_ENV来应用不用的变量就可以啦。

src/utils/axios.js

import config from '@/config'
import HttpRequest from './HttpRequest'

// 根据当前环境获取API根目录
const baseURL = process.env.NODE_ENV === 'production' ? config.baseURL.prod : config.baseURL.dev
// 创建一个HtpRequest对象实例
const axios = new HttpRequest(baseURL)

export default axios

上面中的HttpRequest是对axios的封装,接下来完善HttpRequest这个“类”。

3.2 定义数据属性

class HttpRequest {
   
  // * 设置默认值为空方便使用devServer代理
  constructor (baseURL = '') {
   
    this.baseURL = baseURL
    this.pending = {
   } // 存储每次请求的cancel函数
  }
}

上面我给了baseURL一个默认空字符串,这是因为我们在开发阶段可能会用到代理,如果baseURL不为空,那么代理设置的请求路径就会失效。

3.2 设置默认配置

/**
 *  axios默认配置
 *
 * @return {Object} axios默认配置
 * @memberof HttpRequest
 */
getDefaultConfig () {
   
  return {
   
    baseURL: this.baseURL, // API根路径
    headers: {
   
      // 每次请求带上token
      common: {
   
        Authorization: `Bearer ${
     store.state.token}` || ''
      },
      post: {
   
        'Content-Type': 'application/json; charset=utf-8'
      }
    },
    timeout: 10 * 1000 // 请求超时时间:10s后请求失败
  }
}

上面是Axios的默认请求配置,这里我配置了项目常用的配置,这里说一下Authorization,这个HTTP请求头的作用主要是鉴权,告诉服务器当前请求是否有权限。我这里使用了JWT鉴权机制,所以需要携带token,token放在vuexlocalstorage中存储,所以需要引入Vuex

import store from '@/store'

此外,我还设置了post默认实体请求头为application/json,编码utf-8,这是我们在Web开发中最常用的数据格式了,当然如果是表单类型的提交需要在实际请求中修改实体请求头为:'multipart/form-data'或者'application/x-www-form-urlencoded',同时前者在请求时需要提交一个FormData对象(data:new FormData),而后者可以引入qs库把对象转为这种格式:key1=1value1&key2=value2

3.3 创建Axios实例

有了前面的准备,接下来我们需要借助Axios的create方法来创建一个Axios实例,传入配置然后配置拦截器。

/**
   *
   * 创建Axios实例
   * @param {Object} options 用户传进来的配置
   * @return {Axios} 返回axios实例
   * @memberof HttpRequest
   */
  createAxiosInstance (options) {
   
    const axiosInstance = axios.create()
    // 将默认配置和用户设置的配置进行合并
    
  • 10
    点赞
  • 101
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值