axios的封装

下面是我用promise对按axios的封装
新建一个http.js

import axios from 'axios'
import qs from 'qs'
// options中包含着数据
export default function httpAjax (options, loading = true) {
  return new Promise((resolve, reject) => {
    var data = options.data
    const instance = axios.create({
      timeout: 30000
      // instance创建一个axios实例,可以自定义配置,可在 axios文档中查看详情
      // 所有的请求都会带上这些配置,比如全局都要用的身份信息等。
      // headers: { // 所需的信息放到header头中
      //   // 'Content-Type': 'application/json',
      //   'Authorization': token,
      //   'X-CID': cid,
      //   'X-LOCALE': language,
      //   'X-SIGN': sign_str
      // }
      // timeout: 30 * 1000 //30秒超时
    })
    //loading为true的时候显示加载框,我这里用的是element-ui的加载框
    if (loading) {
      this.$loading({
        lock: true,
        text: 'Loading',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      loading = false
    }
    let httpDefaultOpts = { // http默认配置
      method: options.method,
      url: options.url,
      timeout: 6000,
      params: Object.assign(data),
      data: qs.stringify(Object.assign(data))
      //headers也可以重写会覆盖与合并上面的默认配置
      // headers: options.method=='get'?{
      //     'X-Requested-With': 'XMLHttpRequest',
      //     "Accept": "application/json",
      //     "Content-Type": "application/json; charset=UTF-8",
      //     "Authorization": token
      // }:{
      //     'X-Requested-With': 'XMLHttpRequest',
      //     'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
      //     "Authorization": token
      // }
    }
    if (options.method === 'get') { // 判断是get请求还是post请求
      delete httpDefaultOpts.data
    } else {
      delete httpDefaultOpts.params
    }
    instance(httpDefaultOpts)
      .then(response => { // then 请求成功之后进行什么操作
        this.$loading().close()    //加载框消失
        switch (response.data.code) {
          case 404:
            window.location.href = '/#/error' // 跳转到报错页面
            break
          case 500:
            // 可以提示信息或者跳转到报错页面等
            break
          case 200:
            resolve(response)
            break
        }
      })
      .catch(error => {
        this.$loading().close()
        // console.log('请求异常信息=>:' + options.params + '\n' + '响应' + error)
        reject(error)
      })
  })
}

main.js中

import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import $axios from './assets/http.js'
Vue.prototype.$axios = $axios
Vue.config.productionTip = false
Vue.use(ElementUI)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

页面调取接口使用的时候

 let options = {
        url: process.env.base + '/manager/apply_materials',
        method: 'post',
        data: {
          er_id: 6,
          node_id: 1
        }
      }
      this.$axios(options, true).then(res => {
        console.log(res)
      }).catch(err => {
        console.log(err)
      })

扩展:将axios的拦截也封装进去
http.js封装:

import axios from 'axios'
import qs from 'qs'
// options中包含着数据
export default function httpAjax (options, loading = true) {
  const CancelToken = axios.CancelToken
  return new Promise((resolve, reject) => {
    var data = options.data
    const instance = axios.create({
      timeout: 30000
      // instance创建一个axios实例,可以自定义配置,可在 axios文档中查看详情
      // 所有的请求都会带上这些配置,比如全局都要用的身份信息等。
      // headers: { // 所需的信息放到header头中
      //   // 'Content-Type': 'application/json',
      //   'Authorization': token,
      //   'X-CID': cid,
      //   'X-LOCALE': language,
      //   'X-SIGN': sign_str
      // }
      // timeout: 30 * 1000 //30秒超 时
    })
    if (loading) {
      this.$loading({
        lock: true,
        text: 'Loading',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      loading = false
    }
    let httpDefaultOpts = { // http默认配置
      method: options.method,
      url: options.url,
      timeout: 6000,
      params: Object.assign(data),
      data: qs.stringify(Object.assign(data)),
      // headers: options.method=='get'?{
      //     'X-Requested-With': 'XMLHttpRequest',
      //     "Accept": "application/json",
      //     "Content-Type": "application/json; charset=UTF-8",
      //     "Authorization": token
      // }:{
      //     'X-Requested-With': 'XMLHttpRequest',
      //     'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
      //     "Authorization": token
      // }
      //axios拦截配置
      cancelToken: new CancelToken((cancel) => {
      // 这个参数 cancel 就是CancelToken构造函数里面自带的取消请求的函数,这里把该函数当参数用
        this.cancelFun = cancel  //cancelFun 要在页面的data中定义
      })
    }
    if (options.method === 'get') { // 判断是get请求还是post请求
      delete httpDefaultOpts.data
    } else {
      delete httpDefaultOpts.params
    }
    instance(httpDefaultOpts)
      .then(response => { // then 请求成功之后进行什么操作
        this.$loading().close()
        switch (response.data.code) {
          case 404:
            window.location.href = '/#/error' // 跳转到报错页面
            break
          case 500:
            // 可以提示信息或者跳转到报错页面等
            break
          case 200:
            resolve(response)
            break
        }
      })
      .catch(error => {
        this.$loading().close()
        // console.log('请求异常信息=>:' + options.params + '\n' + '响应' + error)
        reject(error)
      })
  })
}

页面调用的时候:

let options = {
        url: process.env.base + '/manager/apply_materials',
        method: 'post',
        data: {
          er_id: 6,
          node_id: 1
        }
      }
      // this.axios.post('/api/manager/apply_materials', {
      //   er_id: 6,
      //   node_id: 1
      // }).then(res => {
      //   console.log(res)
      // }).catch(err => {
      //   console.log(err)
      // })
      this.$axios(options, true).then(res => {
        console.log(res)
      }).catch(err => {
        console.log(err)
      })
      setTimeout(() => {
        this.cancelFun('请求取消')  //调用cancelFun就会取消请求的发送,
      })

cancelFun函数里面的参数可以打印在页面上,目前只知道这个用处。
在这里插入图片描述

如有不足或者错误之处,欢迎指正

参考了下面两位大佬的文章,特此感谢
https://www.jianshu.com/p/8e0967785c3b?utm_source=oschina-app
https://segmentfault.com/q/1010000017347607

### 如何封装 Axios 以简化 HTTP 请求并增强功能 #### 封装的意义 通过封装 Axios,开发者能够在 Vue 或其他前端框架中统一处理 HTTP 请求,从而提升代码的可维护性和可扩展性。这种封装方式允许配置统一的请求头、拦截器以及错误处理逻辑,减少冗余代码的同时也提高了开发效率[^1]。 --- #### 封装的具体实现步骤 ##### 1. 安装 Axios 在项目中引入 Axios 是第一步操作。可以通过 npm 或 yarn 进行安装: ```bash npm install axios ``` 或者使用 Yarn: ```bash yarn add axios ``` --- ##### 2. 创建 Axios 实例 为了便于管理和定制化需求,通常会创建一个独立的 Axios 实例,并在此基础上进行进一步封装。 ```javascript // src/utils/request.js import axios from 'axios'; const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // 设置基础 URL 地址 timeout: 5000, // 超时时间 (毫秒) headers: { // 默认请求头 'Content-Type': 'application/json', }, }); export default service; ``` 此部分实现了基本的 Axios 配置,包括 `baseURL` 和超时设置等参数[^3]。 --- ##### 3. 添加请求拦截器 请求拦截器用于在发送请求前对数据或配置进行预处理,例如添加 Token 认证信息或其他公共字段。 ```javascript service.interceptors.request.use( config => { const token = localStorage.getItem('token'); // 假设 Token 存储于本地存储 if (token) { config.headers['Authorization'] = `Bearer ${token}`; // 自动携带认证信息 } return config; }, error => { console.error(error); // 打印错误日志 Promise.reject(error); } ); ``` 这段代码展示了如何动态注入 Token 到请求头部,同时提供了错误捕获机制。 --- ##### 4. 添加响应拦截器 响应拦截器负责对接收到的数据进行初步解析和异常处理,确保返回给业务层的是干净的结果。 ```javascript service.interceptors.response.use( response => { const res = response.data; if (res.code && res.code !== 200) { // 如果服务端返回的状态码不正常,则抛出错误 Message.error(res.message || 'Error'); return Promise.reject(new Error(res.message || 'Request failed')); } else { return res; // 返回成功后的数据体 } }, error => { if (error.response) { switch (error.response.status) { case 401: MessageBox.confirm('登录状态已过期,请重新登录', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => { window.location.href = '/login'; // 跳转到登录页 }); break; case 403: Message.error('权限不足'); break; case 404: Message.error('资源未找到'); break; default: Message.error(`服务器内部错误(${error.response.status})`); } } else { Message.error('网络连接失败'); } return Promise.reject(error); } ); ``` 这里不仅完成了常规的成功/失败判断,还针对不同类型的 HTTP 错误进行了个性化提示。 --- ##### 5. 封装通用请求方法 为了让调用更加直观简单,可以提供一些便捷的方法来发起 GET、POST 等常见请求类型。 ```javascript export function get(url, params = {}) { return service.get(url, { params }); } export function post(url, data = {}, options = {}) { return service.post(url, data, options); } ``` 这些函数隐藏了底层细节,使得组件中的实际调用变得非常简洁明了[^2]。 --- ##### 6. 使用封装好的 Axios 实例 最后,在任何需要的地方都可以轻松导入并利用这个经过优化过的工具库完成各种 API 的交互工作。 ```javascript import { get, post } from '@/utils/request'; get('/api/user/info').then(response => { console.log('User Info:', response); }); post('/api/login', { username: 'admin', password: 'password' }) .then(response => { console.log('Login Success:', response); }) .catch(err => { console.error('Login Failed:', err); }); ``` 以上例子说明了如何快速集成封装Axios 来执行具体的接口访问任务。 --- #### 总结 通过对 Axios 的全面封装,不仅可以显著降低重复劳动量,还能有效改善项目的整体架构质量。无论是简单的 CRUD 操作还是复杂的跨域通信场景,都能从中受益匪浅[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值