【axios】封装axios
一、axios简介
定义
Axios
是一个基于 promise
的 HTTP
库,可以用在浏览器和 node.js
中。(本文围绕XHR)
axios
提供两个http
请求适配器,XHR
和HTTP
。
XHR
的核心是浏览器端的XMLHttpRequest
对象;
HTTP
的核心是node
的http.request
方法。
可以先熟悉一下axios官方文档
特性
- 从浏览器中创建XMLHttpRequests
- 从node.js创建http请求
- 支持promise API
- 拦截请求与响应
- 转换请求数据与响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防御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
封装没有一个绝对的标准,且需要结合项目中实际场景来设计。
通用请求应该具备什么
- 正常请求该有的(跨域携带cookie,token,超时设置)
- 请求/响应拦截器
请求成功,业务状态码200,能解析result给我,不用一层一层的去判断拿数据
请求失败,业务状态码非200,说明逻辑判断这是不成功的,全局message提示服务端的报错
http请求非200, 说明http请求都有问题,也全局message提示报错
http请求或者业务状态码401都做注销操作
统一文件下载处理
全局的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相关推荐
- 在vue项目中使用axios封装axios
基本使用 安装 // 项目中安装 npm install axios --S // cdn 引入 <script src="https://unpkg.com/axios/dist/a ...
- axios post object object_一套全面又有实际意义的axios封装+api管理方案
[toc] 前言 功能点 此文主要是基于vuecli3项目中axios封装及api管理的实践记录及过程中的踩坑收获,功能基本都是根据工作中需求实现.需求背景是,在同一套请求配置下,实现以下主要功能: ...
- vue项目内封装axios.,使用Mock,搭建前后端分离环境。Axios + Promise + Mock
1.安装Mock npm install mockjs --save-dev 1.1加入相关Mock代码 在SRC目录下创建文件夹mock,在里面创建虚拟接口地址及数据: // mock/index. ...
- vue项目构建实战基础知识:SPA理解/RESTful接口介绍/static目录配置/axios封装/打包时map文件去除...
一.SPA 不是指水疗.是 single page web application 的缩写.中文翻译为 单页应用程序 或 单页Web应用,更多解释请自行搜索. 所有的前端人员都应该明白我们的页面的 u ...
- axios post body参数_Vue开发中的一些问题(axios封装)
关于Vue开发的问题(axios封装) 在博客中查找vue的axios封装,发现其中案例还是很多的,自己项目中有些需求不够. 比如 1.Content-Type 请求头 application/x-w ...
- vue中的axios封装
import axios from 'axios'; import { Message } from 'element-ui'; axios.defaults.timeout = 5000; axio ...
- 在vue项目中:统一封装 Axios 接口与异常处理
在vue项目中:统一封装 Axios 接口与异常处理 参考文章: (1)在vue项目中:统一封装 Axios 接口与异常处理 (2)https://www.cnblogs.com/itgezhu/p/ ...
- axios设置text html,axios封装动态设置Content-Type
问题如下: 有个问题 是这样的 后台给的API接口 请求类型有两种 'Content-Type': 'application/json' 'Content-Type': 'application/x- ...
- axios队列 vue_(十三 )Vue 封装axios(四种请求)及相关介绍
Vue 封装axios(四种请求)及相关介绍 首先axios是基于promise的http库 promise是什么? 1.主要用于异步计算 2.可以将异步操作队列化,按照期望的顺序执行,返回符合预期的 ...
- 使用async await 封装 axios
es6 的promise 逐步解决了层层回调的问题,es8的async await让异步变成了同步的写法,在vue中,可以通过封装axios,使得所有的请求都可以使用同步写法,同时处理错误信息等,可以 ...
最新文章
- 不要62 ---数位DP
- HealthKit开发快速入门教程之HealthKit开发概述简介
- 题目1165:字符串匹配
- Spring(4)——面向切面编程(AOP模块)
- BASIC-1 闰年判断
- 一文讲透B端产品/C端产品、SaaS/PaaS/IaaS的区别
- 上交大本科毕业,获ICRA最佳学生论文、机器人控制双奖项
- JavaScript css3模拟简单的视频弹幕功能
- linux 该用户组id,linux用户和用户组的一些基本知识
- 软考每日一练||网络工程师
- html磁贴模板,文本磁贴模板(列表文件夹)(HTML)
- 计算机文档怎么字符加宽间距,Word2013设置字符间距,如何设置两个字符之间的距离 -电脑资料...
- 哈尔滨红继红小学计算机名师,【喜报】哈尔滨市20名教师喜获特级教师荣誉称号丨有没有你(认识)的老师...
- 哈希表 matlab实现,MATLAB中的哈希表
- 【有利可图网】PS实战系列:简单易学的PS把照片转素描效果
- 《操作系统》--RR、进程同步、银行家算法及Clock算法复习题
- 顶级免费空间hostinger搭建个人网…
- 如何有效的学习开源代码
- 爱签电子合同联合小五科技,解锁新媒体行业电子合同数字化变局
- java双线_[量化小实验] 双线 RSI 择时策略