vue - vue项目对axios请求的封装

2023-05-16

axios介绍

axios是基于promise的网络请求库,可以在nodejs和浏览器中运行。在服务端axios使用原生的nodejs的http模块,在客户端浏览器中则而是用xmlhttprequests,本质是对XHR的封装,只不过是promise的实现版本;

功能:

  • 从浏览器中创建 XMLHttpRequest
  • 从 node.js 中创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应和转换数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防止 XSRF 攻击

开始封装:

1,新建myAxios.js和backend.js;

myAxios主要是对axios的封装,而backend是对后端状态码的判断;

myAxios.js:

import Axios from 'axios';
import { ErrorToken, GlobalResponseCode, BusinessResponseCode, ApiResult } from '@/api/backend';
import router from '@/router';

// 全局配置
const axios = Axios.create({
  timeout: 60 * 1000, // 超时时间 1分钟
  headers: { 'Content-Type': 'application/json;charset=UTF-8' }, // axios默认的请求类型 json类型进行传输
});

/* 请求拦截处理token的情况 请求头里面可以随意添加属性 */
axios.interceptors.request.use((config) => {
  const token = localStorage.getItem('token');
  if (token) {
    config.headers.authToken = token;
  }
  return config;
});

// 响应拦截
axios.interceptors.response.use(
  (response) => {
    // 我们一般在这里处理,请求成功后的错误状态码 例如状态码是500,404,403
    return Promise.resolve(response);
  },
  (error) => {
    // 服务器响应发生错误时的处理
    Promise.reject(error);
  }
);

/* 定义类 */
/* 注意 get多次相同的请求会出现304  post就不会 */
class MyAxios {
  // 1,get请求
  get(url, params) {
    console.log('params', params);
    return this.request(axios.get(url, params));
  }
  // 2,post请求
  post(url, data) {
    return this.request(axios.post(url, data));
  }
  // 3,put请求
  put(url) {
    return this.request(axios.put(url));
  }

  /**统一响应封装 */
  async request(axiosRequest) {
    try {
      const res = await axiosRequest;// axios请求会返回一个promise所以此处使用await进行接收 如果有异常使用 try catch进行捕获
      // 请求失败的情况
      if (!res.data || res.data.code != '000000') {
        this.resCodePrompt(res.data.code);
        console.warn('SeverError', res);
        // 处理失败结果
        return new ApiResult().setError(res.data);
      }
      // 请求成功的处理
      return new ApiResult().setSuccess(res.data);

    } catch (error) {
      // TODO 这里需要验证失败的情况
      const res = error.response;
      // 根据状态吗进行提示
      this.resErrorPrompt(res);
      return new ApiResult().setNetworkError();
    }
  }

  /**效验返回码 */
  resCodePrompt(resCode) {
    // 判断是否是token的问题
    if (ErrorToken.includes(resCode)) {
      this.$message({ type: 'error', message: '登录凭证无效,请重新登录' });
      router.push('/login');
    }
    // 判断不是token的问题
    const message = GlobalResponseCode[resCode] || BusinessResponseCode[resCode];
    if (message) {
      return this.$message({ type: 'error', message: '登录凭证无效,请重新登录' });
    }
  }

  /**错误的返回码处理 */
  resErrorPrompt(res) {
    if (!res) {
      this.$message({ type: 'error', message: '网络错误!' });
    } else if (res.status === 404) {
      this.$message({ type: 'error', message: '找不到资源!' });
    } else if (res.status === 500) {
      this.$message({ type: 'error', message: '内部错误!' });
    } else {
      // 其余统一提示状态码
      this.$message({ type: 'error', message: `${res.status}` });
    }
  }
}

export const myAxios = new MyAxios();

backend.js

/**结果封装 */
export class ApiResult {
  /**请求是否成功 */
  isSuccess = false;
  /**请求结果状态 */
  stu = RequestStu.success;
  /**状态码 */
  code = '000000';
  /**描述信息 */
  msg = '';
  /**请求结果数据 */
  data = null;

  /**后端返回成功 */
  setSuccess(res) {
    this.isSuccess = true;
    this.stu = RequestStu.success;
    this.msg = res.msg;
    this.data = res.data;
    this.code = res.code;
    console.log('this:', this);
    return this;
  }

  /** 后端返回失败 */
  setError(res) {
    this.stu = RequestStu.error;
    this.msg = res.msg;
    this.code = res.code;
    return this;
  }

  /** 网络错误 */
  setNetworkError() {
    this.stu = RequestStu.networkError;
    return this;
  }
}

/**错误响应吗 关于token验证的 */
export const ErrorToken = ['000002', '000003', '000004'];

/**全局响应码 000000--000100(包括000000和000100)*/
export const GlobalResponseCode = {
  /**成功*/
  '000000': '成功',
  /**请求失败 */
  '000001': '请求失败',
  /**令牌为空 */
  '000002': '请重新登录',
  /**令牌过期 */
  '000003': '请重新登录',
  /**令牌无效 */
  '000004': '请重新登录',
  /**非法请求 */
  '000005': '非法请求',
  /**参数非法 */
  '000006': '参数非法',
  /**参数为空 */
  '000007': '数据为空',
};

/**关于业务逻辑上的响应码 */
export const BusinessResponseCode = {
  /**账号不存在 */
  '000101': '账号信息有误,请确认',
  /**图片验证码不一致 */
  '000102': '图片验证码有误',
  /**短信验证码不一致 */
  '000103': '短信验证码错误',
  /**与保单绑定的手机号不一致 */
  '000104': '手机号有误,请确认',
  /**未勾选同意条款 */
  '000105': '请先勾选保单设计须知。',
  /**短信验证码获取频繁 */
  '000106': '短信验证码获取频繁',
  /**修改保单失败 */
  '000107': '修改失败',
  /**添加保单信息失败 */
  '000108': '添加保单信息失败',
  /**保单已存在 */
  '000109': '保单已存在',
  /**内部错误 */
  '000110': '内部错误',
  /**保单设计已完成 */
  '000111': '保单设计已完成',
  /**获取图片信息失败 */
  '000112': '获取图片失败,请刷新重试',
  '000113': '图片保存失败,请重试',
  '000114': '上传文件过大,请重新上传',
  '000115': '文件上传失败,请重新上传',
  '000116': '已参加该活动',
  '000117': '活动已结束',
  '000118': '参加的活动不存在',
};

/**请求状态 */
export const RequestStu = {
  /** 请求成功 */
  success: 'success',
  /** 请求错误 */
  error: 'error',
  /** 连接失败 */
  networkError: 'networkError',
};

2,使用

1,比如有一个登陆接口 ;我们需要封装一下:

import { myAxios } from '../myAxios';
const prefix = '/backend'
export default {
  /*  请求登录接口 get请求  普通的get请求和post请求 */
  queryLogin(mobileNo) {
    return myAxios.get(`${prefix}/api/user/login`, mobileNo);
  },
};

2,然后再vue组件中请求这个接口:

 methods: {
    async handleLogin() {
      // 非空判断
      if (!this.loginForm.account || !this.loginForm.password) {
        return this.$message('账号或者密码不能为空!');
      }
      // 调用此接口  解构数据
      const { isSuccess, data, code } = await api.login.queryLogin({
        account: 'xinjie1',
        password: '123456789',
      });
      // 请求失败的处理
      if (!isSuccess) {
        return this.$message({ type: 'error', message: code });
      }
      // 请求成功的处理 data
      console.log(data)
		....
    }
  }

3,vue配置接口代理,解决开发环境中的跨域问题;vue.config.js配置如下:

// 服务端ip  需要代理的地址
const api = 'http://10.11.12.181:26341';
  /* 开发环境跨域情况的代理配置 */
  devServer: {
    /* 接口代理器设置 可以配置多个*/
    proxy: {
      '/backend': {
        // 实际访问的服务器地址
        target: api,
        // 控制服务器收到的请求头中Host字段的值  host就是主机名加端口号  实际上就是欺骗后端服务器
        changeOrigin: true,
        // 是否启用websockets
        ws: false,
        // 重写请求路径  开头是/api的替换为 空串
        pathRewrite: { '/api': '' },
      },
    },
  },

4,如果是上传文件,需要使用formData,接口封装需要处理一下:

import { myAxios } from '../myAxios';
const prefix = '/backend'
export default {
 /* formData 文件上传 */
  uploadImg(policyId, policyNo, file) {
    const formData = new FormData();
    formData.append('policyId', policyId.toString());
    formData.append('policyNo', policyNo);
    formData.append('uploadFile', file);
    // 添加文件上传的请求头
    const axiosConfig = {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
      timeout: 10000, //超时时间
      // 表示允许在向服务器发送前,修改请求数据
      transformRequest: [
        function (data, headers) {
          return data;
        },
      ],
    };
    return myAxios.post(`${prefix}/api/user/uploadImg`, formData, { axiosConfig: axiosConfig });
  },
}
 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue - vue项目对axios请求的封装 的相关文章

随机推荐

  • 自用向,当树莓派烧录完rikirobot的镜像后怎么把它变为纯净ros镜像

    1 rikirobot已经安装了大部分的ros包 xff0c 具体镜像可以在tb上购买 xff0c 但他是为了主从机而设定的 xff0c 第一步 xff0c 先安装gedit xff08 密码默认123456 xff09 span clas
  • 机器学习:Linear Discriminant Analysis(过程详解+实例代码MATLAB实现

    目录 LDA概念线性判别分析 xff08 LDA xff09 二分类LDA二分类过程举个例子 线性判别分析 多分类LDA多分类过程 Experiment 3 Linear Discriminant AnalysisLDA二分类讲解LDA二分
  • python编程:从入门到实践 笔记

    文章目录 第二章 变量和简单数据类型2 1 运行 hello world py 时发生的情况2 2 变量2 2 1 变量的命名和使用2 2 2 使用变量时避免命名错误 2 3 字符串2 3 1 使用方法修改字符串的大小写name title
  • 网络层——IP协议

    协议格式网段划分特殊的IP地址IP地址的数量限制私有IP地址和公网IP地址 协议格式 4位版本号 xff1a 指定IP协议的版本 xff0c 对于IPv4来说 xff0c 就是44位首部长度 xff1a 标识IP报头的长度 xff0c 最小
  • 若依 CAS 6.1 java.io.FileNotFoundException: \etc\cas\thekeystore (系统找不到指定的文件。)

    参考文章 实际上语文水平不过关 xff0c 把cas resources内部的文件全部拷贝到cas overlay template src main resources下
  • 解决通过vnc登陆linux server,在terminal最小化后找不到的问题

    在左边的菜单栏右击 xff0c add new panel xff0c 再右击新添加的add to panel xff0c 然后会让你选择往这个新panel上添加新的菜单 xff0c 把window list添加就好了
  • CSS第二章:2.颜色单位(RGB值、RGBA值)

    总览 一 RGB 1 CSS中能够使用颜色名来使用颜色 2 不使用颜色名 xff0c 我们使用RGB值来描述颜色 3 R red G green B blue 4 每一种颜色的范围在0 255 xff08 0 100 xff09 之间 5
  • 信息化与数字化的区别

    数字化与信息化的区别 今日看到一篇文章 信息化与数字化的核心差异 xff0c 让我重新思考了这两个即熟悉又陌生的名词 xff0c 通过这篇文章和在B站上搜相对应的视频 xff0c 使我大致懂了一些 1 信息化是什么 xff1f 信息化是数据
  • 开启快乐之旅—【C#Winform&认识篇】

    入门学习 简单了解熟悉界简单操作1 xff1a 修改窗体标题2 xff1a 修改窗体图标3 xff1a 窗体出现位置4 xff1a 最大化 xff0c 最小化操作5 xff1a 是否任务栏显示form窗体6 xff1a 窗口大小 简单了解
  • ubuntu磁盘清理

    打开ubuntu software 搜索Bleachbit 安装即可 系统清理工具BleachBit使用 ubuntu清理磁盘空间的多种方法 Ubuntu上释放磁盘空间的几种简单方法 Ubuntu 安装 BleachBit 也可 1 查看电
  • 一些网站资源分享

    链接地址 网站地址 1 博客就是这个博客 2 音乐是我网易云歌单 3 图床是我保存的图库 4 西瓜导航里面有各种网站 5 钟馗之眼是一个爬虫全网某些特征的网站 6 罗马盘是资源网站 7 AI引擎 xff0c 体验智能的感觉 8 优店 xff
  • 软件工程的完整生命周期

    生命周期大体上分为11个步骤 xff0c 如下图 xff1a 第一步 xff1a 概念 创意 需求 产生 xff0c 这个环节一般是项目发起人完成 xff0c 也有可能由产品经理或收到反馈后发起 xff0c 很多时候是会带有这个项目的期望或
  • Qt-设置背景色的几种方式

    最近设置背景色 xff0c 被背景色搞得晕头转向 xff0c 然后总结了一下用过的方法与踩过的坑 xff0c 希望大家有所帮助 QLabel label 61 new QLabel CSS样式 xff0c 直接设置样式 xff0c 该方法对
  • C++ 如何获取数组/容器的长度?

    文章目录 一 获取数组的长度1 sizeof a sizeof a 2 end a begin a 二 获取标准库容器的长度三 数组作为函数参数时 xff0c 在函数中无法获取其长度 一 获取数组的长度 1 sizeof a sizeof
  • 计算机网络期末复习题

    1 请简述在划分子网的情况下 xff0c 路由器转发IP数据报的基本过程 答 xff1a 在划分子网的情况下 xff0c 路由器转发分组的算法如下 xff1a 1 从收到的数据报首部提取目的IP地址D xff08 1分 xff09 2 先判
  • Jetson TX1 TX2 IO 引脚设置

    有朋友问我引脚问题 xff0c 我就把一段文档摘抄在这里了 希望对大家有用 配置40引脚扩展接头 主屏幕 兼容的硬件屏幕 40引脚扩展标题屏幕 命令行界面 设备树覆盖 创建简单的设备树覆盖 为40针接头连接器创建自定义设备树覆盖 启动Jet
  • Android手机怎样投屏到win10(无需联网)

    一 前言 适用场景 xff1a 无可用wifi 想获得大屏观影体验 x1f601 二 具体操作 PC端 在Cortana处搜索 投影设置 投影到此电脑 处的设置如下如图 xff08 也可根据自己习惯调整 xff09 安卓端 华为手机为例 打
  • Windows远程控制ubuntu16.04的vnc教程(附灰屏和无鼠标只显示叉号的解决方案)

    VNC可远程Linux的桌面 xff0c 不仅仅只可以远程终端窗口 xff0c 操作起来要比ssh好用 xff0c 效果如图 VNC介绍 xff1a VNC Virtual Network Console xff0c 即虚拟网络控制台 xf
  • 联邦学习安全与隐私保护

    一 FL隐私保护方法 1 1 加密方法 通过将明文编码为密文的方式 xff0c 只允许特定人员解码 xff0c 为数据隐私保护提供了有效手段 xff0c 但往往需要较大的计算开销 xff0c 较难应用于实际场景中 安全多方计算 SMC研究的
  • vue - vue项目对axios请求的封装

    axios介绍 axios是基于promise的网络请求库 xff0c 可以在nodejs和浏览器中运行 在服务端axios使用原生的nodejs的http模块 xff0c 在客户端浏览器中则而是用xmlhttprequests xff0c