小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
axios简单封装
一、前言
之前开发的时候都是需要发送请求的时候直接调用axios的静态方法,一些配置项就会重复地配置,显得代码非常冗余。实习的时候公司对于axios进行了一层封装,可以让代码更简洁一点,也便于维护。这篇文章主要就介绍axios简单封装的方法。当然封装的方法非常多,选择合适的就好了。
二、结构
大致分为了3个模块
- http/
-index.js
-request.js
-resCodehandler.js
1. index.js
主要是将封装好的模块导出
// index.js
/**
* @description: 通用请求模块封装
*/
import axios from 'axios';
import request from './request';
export { axios, request };
export default request;
2. request.js
主要的功能:
- 创建axios实例
- 可复用的配置项
- 自定义请求和响应拦截器
- 导出axios实例
这里可以在响应拦截器中对业务逻辑作进一步的判断。
// request.js
import axios from 'axios'
import qs from 'qs'
import resCodehandler from './resCodehandler'
// create an axios instance with a custom config
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
timeout: 5000, // request timeout
headers: {
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
// "Content-Type": "application/json;charset=utf-8",
// 'X-Custom-Header': 'foobar'
}, // The custom headers
transformRequest: [function (data, headers) {
// Do whatever you want to transform the data
console.log(headers)
data = qs.stringify(data); // 使用工具qs来处理参数,处理发送请求的参数,序列化字符串
return data;
}],
transformResponse: [function (data) {
// Do whatever you want to transform the data
return data;
}],
})
const requestHandler = config => {
// do something before request is sent
config.headers['token'] = `admin token`
config.headers['appCode'] = `appCode` // The custom headers
return config
}
const requestErrHandler = error => {
// do something with request error
console.log(`error : ${error}`) // for debug
return Promise.reject(error)
}
const responseHandler = response => {
// Do something with response data
const res = response.data
// if the custom code is not Logically correct, it is judged as an error.
// 在这里可以对response进行业务上的逻辑判断,具体逻辑可以自定义。
if (res.code && res.code !== 20000) {
// 通过Promise.reject方法,返回值会被认为是error处理
return Promise.reject(new Error(res.message || 'Error'))
}
// 可以自定义返回的数据,比如可以只返回res
return response
}
const responseErrHandler = error => {
// Do something with response error
resCodehandler(error);
console.log(`error : ${error}`) // for debug
return Promise.reject(error)
}
// Add a request interceptor
service.interceptors.request.use(requestHandler, requestErrHandler)
// Add a response interceptor
service.interceptors.response.use(responseHandler, responseErrHandler
)
export default service
3. resCodehandler.js
主要的功能:
- 自定义错误处理 主要包括控制逻辑和业务逻辑的错误。
这里也可能存在控制逻辑为正常,但业务逻辑不正常的情况。比如采用两级状态码(HTTP状态码,业务状态码),这样就需要更细化区分不同的情况做出处理。
import { Message } from "element-plus";
import router from '../../router'
const CODE_MESSAGE = {
200: '服务器成功返回请求数据',
201: '新建或修改数据成功',
202: '一个请求已经进入后台排队(异步任务)',
204: '删除数据成功',
400: '发出信息有误',
401: '用户没有权限(令牌、用户名、密码错误)',
403: '用户得到授权,但是访问是被禁止的',
404: '访问资源不存在',
406: '请求格式不可得',
410: '请求资源被永久删除,且不会被看到',
500: '服务器发生错误',
502: '网关错误',
503: '服务不可用,服务器暂时过载或维护',
504: '网关超时',
};
// 提示语可以传入也可以匹配默认值
const info = function (status, MESSAGE = CODE_MESSAGE[`${status}`]) {
return Message({
showClose: true,
message: `${MESSAGE}`,
type: "error",
duration: "5000"
});
}
const resCodehandler = function (res) {
switch (res.status) {
case 400: {
info(res.status)
break
}
case 401: {
//对于相同的HTTP状态码,如果业务还需要细分,可以再添加一个属性来区分
if ([118000014, 118000015, 118000016].includes(res.code)) {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
}
break;
}
// 403 比如token过期
case 403: {
info(res.status)
localStorage.removeItem('token');
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
break
}
case 404: {
info(res.status)
// 也可以自定义页面
// router.push({
// path: "/error/404"
// });
break
}
case 406: {
info(res.status)
break
}
case 500: {
info(res.status)
break
}
case 502: {
info(res.status)
break
}
case 503: {
info(res.status)
break
}
case 504: {
info(res.status)
break
}
default:{
info(res.status,'未知错误')
break
}
}
}
export {
resCodehandler
}
三、用法
- 先引入request模块
- 然后调用即可
import request from "../utils/http";
export const init_get = data => {
return request({
url: `http://localhost:3000/posts/${data}`,
method: "get",
})
}
export const init_post = data => {
return request({
url: "http://localhost:3000/posts",
method: "post",
data: {
title: "今天天气不错, 还挺风和日丽的",
author: "Alice"
}||data
})
}