一、axios简介

定义

Axios 是一个基于 promiseHTTP 库,可以用在浏览器和 node.js 中。(本文围绕XHR)

axios提供两个http请求适配器,XHRHTTP
XHR的核心是浏览器端的XMLHttpRequest对象;
HTTP的核心是nodehttp.request方法。

可以先熟悉一下axios官方文档

特性

  1. 从浏览器中创建XMLHttpRequests
  2. 从node.js创建http请求
  3. 支持promise API
  4. 拦截请求与响应
  5. 转换请求数据与响应数据
  6. 取消请求
  7. 自动转换JSON数据
  8. 客户端支持防御XSRF

简单使用

import axios from 'axios';// 为给定ID的user创建请求
axios.get('/user?ID=12345')   .then(function (response) {     console.log(response);   })   .catch(function (error) {    console.log(error);   });  // 上面的请求也可以这样做
axios.get('/user', { params: {ID: 12345} })   .then(function (response) {     console.log(response);   })   .catch(function (error) {     console.log(error);   });// 支持async/await用法
async function getUser() {try {const response = await axios.get('/user?ID=12345');console.log(response);} catch (error) {console.error(error);}
}

二、为什么要封装axios? 如何封装?

axios的API很友好,可以在项目中直接使用。
但是在大型项目中,http请求很多,且需要区分环境, 每个网络请求有相似需要处理的部分,不封装会导致代码冗余,破坏工程的可维护性,扩展性。
axios封装没有一个绝对的标准,且需要结合项目中实际场景来设计。

通用请求应该具备什么

  1. 正常请求该有的(跨域携带cookie,token,超时设置)
  2. 请求/响应拦截器
  • 请求成功,业务状态码200,能解析result给我,不用一层一层的去判断拿数据

  • 请求失败,业务状态码非200,说明逻辑判断这是不成功的,全局message提示服务端的报错

  • http请求非200, 说明http请求都有问题,也全局message提示报错

  • http请求或者业务状态码401都做注销操作

  1. 统一文件下载处理

  2. 全局的loading配置, 默认开启,可配置关闭(由于后端的问题,经常会让前端加防抖节流或者loading不让用户在界面上疯狂乱点)

请求头

常见以下三种

(1)application/json

参数会直接放在请求体中,以JSON格式的发送到后端。这也是axios请求的默认方式。这种类型使用最为广泛。

(2)application/x-www-form-urlencoded

请求体中的数据会以 普通表单形式(键值对) 发送到后端。

(3)multipart/form-data

参数会在请求体中,以标签为单元,用分隔符(可以自定义的boundary)分开。既可以上传键值对,也可以上传文件。通常被用来上传文件的格式

封装例子

import _Vue from 'vue';
import axios, { AxiosInstance, AxiosResponse, AxiosRequestConfig } from 'axios';
import { CryptUtil } from '@/utils/CryptUtil';
// import { MAINHOST, QAHOST, commonParams } from '@/config';
// import { getToken } from '@/utils/common';
// import qs from 'qs';
import router from '@/router'class AxiosHttpRequest {private axios: AxiosInstance;private dischargedApi: Array<string> = ['/system/api/searchHumanName','/system/api/login','/system/api/template','/system/api/info/sysconfig/item','/system/api/unitinfo/loadaddress']constructor(ax: any) {this.axios = ax;// axios 配置this.axios.defaults.timeout = 120 * 1000;// this.axios.defaults.baseURL = process.env.NODE_ENV === 'production' ? MAINHOST : QAHOST;// @ts-ignorethis.axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';// this.axios.defaults.baseURL = 'http://119.3.251.200:8097';// http request 拦截器this.axios.interceptors.request.use((config: AxiosRequestConfig) => {// 在此处添加请求头等,如添加tokenif (sessionStorage.getItem('token')) {// @ts-ignoreconfig.headers['Authorization'] = sessionStorage.getItem('token');// @ts-ignoreconfig.headers['Verify'] = CryptUtil.desEncrypt(new Date().getTime() + '');} else {// @ts-ignoreif (this.dischargedApi.includes(config.url)) {// @ts-ignoreconfig.headers['Authorization'] = 'eyJhbGciOiJIUzUxMiJ9.eyJISSI6LTEsIlVJIjoxLCJITiI6IumZtuaYjum-mSIsIlJJIjoiIiwiVU4iOiLlub_opb_lo67ml4_oh6rmsrvljLoiLCJVQyI6Ii8xLyJ9.DAWCZpyQSAngIv4NBIxxz19mrLGvHdZI8WdNim5wlI0yZoa0WkHCrb-tyDY4v1MpbpEl4TWEOndnZmxxdma0YQ';// @ts-ignoreconfig.headers['Verify'] = CryptUtil.desEncrypt(new Date().getTime() + '');}}let sysConfigMap = JSON.parse(sessionStorage.getItem('sysConfigMap') as string);if (sysConfigMap) {let WEB_API_ENCRYPT_LIST = JSON.parse(sessionStorage.getItem('sysConfigMap') as string).WEB_API_ENCRYPT_LIST || [];if (WEB_API_ENCRYPT_LIST.length > 0) {WEB_API_ENCRYPT_LIST = WEB_API_ENCRYPT_LIST.split(';');for (let i = 0; i < WEB_API_ENCRYPT_LIST.length; i++) {// @ts-ignoreif (config.url.indexOf(WEB_API_ENCRYPT_LIST[i]) > -1) {// @ts-ignoreconfig.headers['encry'] = 'true';config.data = { data: CryptUtil.desEncrypt(JSON.stringify(config.data)) }break;}}}}return config;},(error: any) => {return Promise.reject(error);});// http response 拦截器this.axios.interceptors.response.use((response: AxiosResponse) => {if (response.headers['encry'] === 'true') {// @ts-ignoreresponse.data['data'] = JSON.parse(CryptUtil.desDecrypt(response.data.data));}return response;},(error: any) => {if (error.response.data?.message) {error.message = error.response.data.message;} else if (error && error.response) {switch (error.response.status) {case 400: error.message = '请求错误(400)'; break;case 401: error.message = '未授权,请重新登录(401)'; break;case 403: error.message = '拒绝访问(403)'; break;case 404: error.message = `请求地址错误: ${error.response.config.url}`; break;case 405: error.message = '请求方法未允许(405)'; break;case 408: error.message = '请求超时(408)'; break;case 500: error.message = '服务端内部错误(500)'; break;case 501: error.message = '服务未实现(501)'; break;case 502: error.message = '网络错误(502)'; break;case 503: error.message = '服务不可用(503)'; break;case 504: error.message = '网络超时(504)'; break;case 505: error.message = 'HTTP版本不受支持(505)'; break;default: error.message = `连接错误: ${error.message}`;}} else if (error.message.includes('timeout')) {error.message = '请求超时';} else {// error.message = '连接服务器失败,请联系管理员';}if (error && error.response && (error.response.status === 401 || error.response.status === 403)) {_Vue.prototype.$message.warning({content: "token失效,请重新登录",duration: 3,onClose: () => {// 清除tokensessionStorage.clear();// window.close();router.push({ name: 'Login' });}});} else {_Vue.prototype.$message.error(error.message);}return Promise.reject(error.response);});}public get(url: string, params: object, config: object) {//增加时间戳 防止缓存params = {_t: new Date().getTime(),...params}return this.axios({method: 'get',url,params,...config,}).then((res: any) => {if (res && res.data) {if (!res.data.ok) {_Vue.prototype.$message.error(res.data.message ? res.data.message : "");return;}return res.data.data || res.data.dataMap;}});}// 获取静态资源public getStatic(url: string, params: object, config: object) {//增加时间戳 防止缓存params = {_t: new Date().getTime(),...params}return this.axios({method: 'get',url,params,...config,}).then((res: any) => {if (res && res.data) {return res.data;} else {_Vue.prototype.$message.error('资源获取失败!');}});}public getTrace(url: string, params: object, config: object) {//增加时间戳 防止缓存params = {_t: new Date().getTime(),...params}return this.axios({method: 'get',url,params,...config,}).then((res: any) => {if (res && res.data) {return res.data.data || res.data.dataMap;}});}public post(url: string, params: object) {return this.axios({method: 'post',url,// data: qs.stringify(params),data: params,}).then((res: any) => {if (res && res.data) {if (!res.data.ok) {_Vue.prototype.$message.error(`${res.data.message ? `${res.data.message}` : ""}`,);return;}return res.data.data || res.data.dataMap;}});}public postJson(url: string, params: object, config: object, need:boolean = true) {return this.axios({method: 'post',url,data: JSON.stringify(params),headers: { "Content-Type": "application/json", ...config },transformRequest: [function (data, headers) {// @ts-ignoreif (!need && headers.Authorization) {// @ts-ignoredelete headers.Authorization;}// @ts-ignoreif (!need && headers.Verify) {// @ts-ignoredelete headers.Verify;}return data;}]}).then((res: any) => {if (res && res.data) {if ((res.data.hasOwnProperty("success") && !res.data.success) || (res.data.hasOwnProperty("hasError") && res.data.hasError)) {_Vue.prototype.$Notice.error({title: "请求失败",desc: res.data.message ? res.data.message : ""});return;}return res.data.data || res.data.dataMap;}});}public uploadFile(url: string, data: FormData, config1?: object) {let config = {// 请求头信息headers: { 'Content-Type': 'multipart/form-data' },...config1};return this.axios.post(url, data, config).then((res: any) => {if (res && res.data) {if (!res.data.ok) {_Vue.prototype.$Notice.error({title: "请求失败",desc: res.data.message ? res.data.message : ""});return;}return res.data.data || res.data.dataMap;}});}public getData(url: string, params: object) {return this.axios({method: 'get',url,params: params,responseType: 'blob'}).then((res) => {let url = window.URL.createObjectURL(new Blob([res.data]));let link = document.createElement('a');link.style.display = 'none';link.href = url;// @ts-ignorelink.setAttribute('download', params['fileName']);document.body.appendChild(link);link.click();document.body.removeChild(link);});}public postData(url: string, fileName: string, params: object) {return this.axios({method: 'post',url,data: params,responseType: 'blob'}).then((res) => {let url = window.URL.createObjectURL(new Blob([res.data]));let link = document.createElement('a');link.style.display = 'none';link.href = url;// @ts-ignorelink.setAttribute('download', fileName);document.body.appendChild(link);link.click();document.body.removeChild(link);});}
}const $axios: AxiosHttpRequest = new AxiosHttpRequest(axios);
export function AxiosRequest(Vue: typeof _Vue): void {Vue.prototype.$axios = $axios;
}

使用

async loadReportFields() {this.tableData = await Service.loadReportFields({ reportId: this.reportId });
}
import Vue from "vue";const config = `/report/api/config/`;
const configCond = `/report/api/config/cond/`;
const configStatis = `/report/api/config/statis/`;
const configAuth = `/report/api/config/auth/`;
const statis = `/report/api/statis/`;export const loadReportFields = (params: any) => {return Vue.prototype.$axios.get(`${config}loadfields`, params);
};export const updateReport = (params: any) => {return Vue.prototype.$axios.post(`${config}update`, params);
};

参考 https://juejin.cn/post/6999932338566070308#heading-12

【axios】封装axios相关推荐

  1. 在vue项目中使用axios封装axios

    基本使用 安装 // 项目中安装 npm install axios --S // cdn 引入 <script src="https://unpkg.com/axios/dist/a ...

  2. axios post object object_一套全面又有实际意义的axios封装+api管理方案

    [toc] 前言 功能点 此文主要是基于vuecli3项目中axios封装及api管理的实践记录及过程中的踩坑收获,功能基本都是根据工作中需求实现.需求背景是,在同一套请求配置下,实现以下主要功能: ...

  3. vue项目内封装axios.,使用Mock,搭建前后端分离环境。Axios + Promise + Mock

    1.安装Mock npm install mockjs --save-dev 1.1加入相关Mock代码 在SRC目录下创建文件夹mock,在里面创建虚拟接口地址及数据: // mock/index. ...

  4. vue项目构建实战基础知识:SPA理解/RESTful接口介绍/static目录配置/axios封装/打包时map文件去除...

    一.SPA 不是指水疗.是 single page web application 的缩写.中文翻译为 单页应用程序 或 单页Web应用,更多解释请自行搜索. 所有的前端人员都应该明白我们的页面的 u ...

  5. axios post body参数_Vue开发中的一些问题(axios封装)

    关于Vue开发的问题(axios封装) 在博客中查找vue的axios封装,发现其中案例还是很多的,自己项目中有些需求不够. 比如 1.Content-Type 请求头 application/x-w ...

  6. vue中的axios封装

    import axios from 'axios'; import { Message } from 'element-ui'; axios.defaults.timeout = 5000; axio ...

  7. 在vue项目中:统一封装 Axios 接口与异常处理

    在vue项目中:统一封装 Axios 接口与异常处理 参考文章: (1)在vue项目中:统一封装 Axios 接口与异常处理 (2)https://www.cnblogs.com/itgezhu/p/ ...

  8. axios设置text html,axios封装动态设置Content-Type

    问题如下: 有个问题 是这样的 后台给的API接口 请求类型有两种 'Content-Type': 'application/json' 'Content-Type': 'application/x- ...

  9. axios队列 vue_(十三 )Vue 封装axios(四种请求)及相关介绍

    Vue 封装axios(四种请求)及相关介绍 首先axios是基于promise的http库 promise是什么? 1.主要用于异步计算 2.可以将异步操作队列化,按照期望的顺序执行,返回符合预期的 ...

  10. 使用async await 封装 axios

    es6 的promise 逐步解决了层层回调的问题,es8的async await让异步变成了同步的写法,在vue中,可以通过封装axios,使得所有的请求都可以使用同步写法,同时处理错误信息等,可以 ...

最新文章

  1. 不要62 ---数位DP
  2. HealthKit开发快速入门教程之HealthKit开发概述简介
  3. 题目1165:字符串匹配
  4. Spring(4)——面向切面编程(AOP模块)
  5. BASIC-1 闰年判断
  6. 一文讲透B端产品/C端产品、SaaS/PaaS/IaaS的区别
  7. 上交大本科毕业,获ICRA最佳学生论文、机器人控制双奖项
  8. JavaScript css3模拟简单的视频弹幕功能
  9. linux 该用户组id,linux用户和用户组的一些基本知识
  10. 软考每日一练||网络工程师
  11. html磁贴模板,文本磁贴模板(列表文件夹)(HTML)
  12. 计算机文档怎么字符加宽间距,Word2013设置字符间距,如何设置两个字符之间的距离 -电脑资料...
  13. 哈尔滨红继红小学计算机名师,【喜报】哈尔滨市20名教师喜获特级教师荣誉称号丨有没有你(认识)的老师...
  14. 哈希表 matlab实现,MATLAB中的哈希表
  15. 【有利可图网】PS实战系列:简单易学的PS把照片转素描效果
  16. 《操作系统》--RR、进程同步、银行家算法及Clock算法复习题
  17. 顶级免费空间hostinger搭建个人网…
  18. 如何有效的学习开源代码
  19. 爱签电子合同联合小五科技,解锁新媒体行业电子合同数字化变局
  20. java双线_[量化小实验] 双线 RSI 择时策略

热门文章

  1. 【硬件】对电源模块的梳理2.0(含LDO参数详解、DCDC参考设计)
  2. 外包开发APP这些正式流程事项你需要了解,这些坑你必须知道!
  3. QT基础入门【Demo篇】QT定时器的使用方法
  4. 量化回测平台Backtrader实战-陆一潇-专题视频课程
  5. 【数字逻辑】如何根据真值表的内容写出对应的逻辑关系式?
  6. HDMI转MIPI CSI东芝转换芯片:TC358743XBG/TC358749XBG(\w Scaler)
  7. 安装UltralSO教程
  8. 基于神经网络的自适应最优控制
  9. LiteOS内核开发(一)
  10. 「娃娃分享」-个人总结的一个VMP脱壳步骤.