本文是我们团队每周分享的内容,该内容是由导师整理分享的。Eaxios 是我们前端团队自己在用的库,由导师封装的,因为其他小伙伴对它有所好奇,所以才有该篇的分享内容。
专注于为中小企业提供成都网站设计、成都网站建设服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业东营区免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了上千家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
正文开始~~
Eaxios 是基于 axios 封装的网络请求库,在保持 API 与 axios 基本一致的情况下,简化服务端响应内容和各种异常情况的处理。
如上图所示,是一次 Ajax 请求可能输出的结果,在前端我们需要根据输出结果给用户不同的提示。
但是,现有的 Axios 库对于异常结果没有提供较好的封装,Axios Promise catch 里包含各种类型的错误,而且没有提供错误码来识别请求失败的原因。而且很多服务端接口会返回自己的错误码,这样在 Axios Promise then 里也需要处理业务异常。
此外,Axios 本身如下所述的一些问题和局限性。
对于 500 等错误,响应内容会丢失,所以不要去配置 responseType 为 json,对于使用者来说容易采到这个坑。
ps:虽然 Axios 官方文档声明 responseType 是 json,实际上底层调用 XMLHttpRequest 的 responseType 是没有传值的,应该是为了规避这个问题。
ps:应该是为了规避上一个问题,默认提供了一个响应处理函数进行 JSON 解析,但是这会影响性能(500 等响应内容值较多时,会造成页面卡顿)。虽然 transformResponse 可以转换 response,实际接收到的参数是 response.data,所以无法判断具体情况来决定是否进行解析 JSON。
理想情况下,使用者希望 then 返回有效的数据,catch 返回各种错误情况:请求被取消、网络异常、网络超时、服务端异常、服务端数据格式错误、业务异常。
优化方案:
eaxios 主要对响应的处理做了一些优化,除了以下部分,eaxios 的 api 与 axios 保持一致:
- const eaxios = require('eaxios');
- eaxios.defaults.transformResponse = [
- function (data, response) {
- if (typeof data === 'object') {
- // 默认约定有成功解析 JSON 对象,就认为服务端成功响应,且有提供错误码
- if (data.code === 0) {
- return data.data;
- } else {
- throw eaxios.createError(data.message, data.code, response);
- }
- } else {
- // 50x 等服务异常情况
- throw eaxios.createError(
- data,
- response.config.responseError.SERVER_ERROR,
- response
- );
- }
- },
- ];
- return eaxios('https://run.mocky.io/v3/4f503449-0349-467e-a38a-c804956712b7')
- .then((data) => {
- console.log('success', data.id);
- })
- .catch((error) => {
- console.log('failure', error.code); // UNKNOWN、REQUEST_OFFLINE、REQUEST_TIMEOUT、SERVER_ERROR、RESPONSE_INVALID 和业务错误码
- });
ps:如果存在服务单接口请求规范,可以通过 eaxios.create 创建适用于不同接口规范的请求函数。
- interface EaxiosError
extends Error { - config: EaxiosRequestConfig;
- code?: string;
- request?: any;
- response?: EaxiosResponse
; - isAxiosError: boolean;
- toJSON: () => object;
- }
错误处理函数可以根据错误码 code 来处理异常,code 可能的值为 UNKNOWN、REQUEST_OFFLINE、REQUEST_TIMEOUT、SERVER_ERROR、RESPONSE_INVALID 和其他业务错误码。ps:如果要定制错误码,可以在请求配置中添加配置项 `responseError`。
- eaxios.defaults.responseError = {
- REQUEST_OFFLINE: '1'REQUEST_OFFLINE
- };
下面以 { 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
- require("core-js/modules/web.url-search-params.js")
新闻名称:我司是怎么封装Axios来处理百万级流量中平时少见过的问题
文章源于:http://www.shufengxianlan.com/qtweb/news36/80186.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联