本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。
本文是我们团队每周分享的内容,该内容是由导师整理分享的。Eaxios 是我们前端团队自己在用的库,由导师封装的,因为其他小伙伴对它有所好奇,所以才有该篇的分享内容。
正文开始~~
Eaxios 是基于 axios 封装的网络请求库,在保持 API 与 axios 基本一致的情况下,简化服务端响应内容和各种异常情况的处理。
如上图所示,是一次 Ajax 请求可能输出的结果,在前端我们需要根据输出结果给用户不同的提示。
但是,现有的 Axios 库对于异常结果没有提供较好的封装,Axios Promise catch 里包含各种类型的错误,而且没有提供错误码来识别请求失败的原因。而且很多服务端接口会返回自己的错误码,这样在 Axios Promise then 里也需要处理业务异常。
此外,Axios 本身如下所述的一些问题和局限性。
content-type
为 application/x-www-form-urlencoded
类型的请求体,使用起来不够方便优化方案:
eaxios 主要对响应的处理做了一些优化,除了以下部分,eaxios 的 api 与 axios 保持一致:
eaxios 请求配置的 transformResponse 传参和处理时机发生了变化
假设服务端返回的数据结构为 { code: 0, message: 'success', data: {} }
,code 为 0 表示正确的响应,非 0 表示异常,接口请求的代码示例如下所示:
ps:如果存在服务单接口请求规范,可以通过 eaxios.create 创建适用于不同接口规范的请求函数。
eaxios 的请求处理函数 then 只会接收到 transformResponse 转换后的数据,对于网络、超时、服务端异常和业务异常等问题,会在 catch 接收一个 EaxiosError 类型的错误对象。
错误处理函数可以根据错误码 code 来处理异常,code 可能的值为 UNKNOWN、REQUEST_OFFLINE、REQUEST_TIMEOUT、SERVER_ERROR、RESPONSE_INVALID 和其他业务错误码。
eaxios.defaults.responseError = {
REQUEST_OFFLINE: '1'REQUEST_OFFLINE
};
eaxios 内部会自动序列化表单类型的请求参数,所以主要传对象给 data 就行了。
下面以 { code: 0, message: 'success', data: { } }
这样的接口规范为例,演示如何使用 eaxios。
const eaxios = require('..');
const request = eaxios.create({
baseURL: 'https://run.mocky.io/v3',
timeout: 30000,
transformResponse: [
function (data, response) {
if (typeof data === 'object') {
if (data.code === 0) {
return data.data;
} else {
throw eaxios.createError(data.message, data.code, response);
}
} else {
throw eaxios.createError(
data,
response.config.responseError.SERVER_ERROR,
response,
);
}
},
],
});
request.interceptors.response.use(
function (response) {
return response;
},
function (error) {
if (error && error.code) {
if (error.code === 'UNKNOWN') {
console.log('未知错误');
} else if (error.code === 'REQUEST_OFFLINE') {
console.log('网络未连接');
} else if (error.code === 'REQUEST_TIMEOUT') {
console.log('网络有点慢,请求超时了');
} else if (error.code === 'SERVER_ERROR') {
console.log('系统出问题了');
} else if (error.code === 'RESPONSE_INVALID') {
console.log('服务端 bug');
} else if (error.code === '10000') {
// 假设 10000 为登录会话过期
console.log('登录会话失效');
} else {
console.log('根据情况是否要消息提示,还是外部处理')
}
}
throw error;
},
);
function printError(error) {
console.log(
`code: ${error.code}, name: ${error.name}, message: ${error.message}, isAxiosError: ${error.isAxiosError}, stack:\n${error.stack}`,
);
}
function success() {
console.log('>> success');
return request('/4f503449-0349-467e-a38a-c804956712b7')
.then((data) => {
console.log('success', data);
})
.catch((error) => {
printError(error);
});
}
function failure() {
console.log('>> failure');
return request('/42d7c21d-5ae6-4b52-9c2d-4c3dd221eba4')
.then((data) => {
console.log('success', data);
})
.catch((error) => {
printError(error);
});
}
function invalid() {
console.log('>> invalid');
return request('/1b23549f-c918-4362-9ac8-35bc275c09f0')
.then((data) => {
console.log('success', data);
})
.catch((error) => {
printError(error);
});
}
function server_500() {
console.log('>> server_500');
return request('/2a9d8c00-9688-4d36-b2de-2dee5e81f5b3')
.then((data) => {
console.log('success', data);
})
.catch((error) => {
printError(error);
});
}
success().then(failure).then(invalid).then(server_500);
/* log
>> success
success { id: 1 }
>> failure
登录会话失效
code: 10000, name: Error, message: error, isAxiosError: true, stack: ...
>> invalid
服务端 bug
code: RESPONSE_INVALID, name: SyntaxError, message: Unexpected token V in JSON at position 0, isAxiosError: true, stack: ...
>> server_500
系统出问题了
code: SERVER_ERROR, name: Error, message: ..., stack: ...
*/
eaxios 依赖 URLSearchParams 处理表单类型的请求参数,不支持的环境需要引入响应的 polyfill
代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
文章每周持续更新,本文 GitHub https://github.com/qq449245884/xiaozhi 已经收录,整理了很多我的文档,欢迎Star和完善,大家面试可以参照考点复习