本篇文章为大家展示了Ant Design Pro 5 网络请求和错误处理是怎样的,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
Ant Design Pro 5 的网络请求有点复杂,只看文档不阅读源码搞不清楚到底发生了什么事情。涉及到fetch umi-request @umijs/plugin-request Ant Design Pro 5相关代码。
代替XMLHttpRequest的访问和操纵HTTP的技术。fetch最大的问题是,只有在发生网络故障时或请求被阻止时,才抛出异常;而对于 HTTP 状态码为 404 或 500 之类的情况,会认为是正常的响应,并不会抛出异常。
参考资料:Fetch API
基于 fetch 封装,提供诸如缓存、超时、字符编码处理、错误处理等功能。其中错误处理与开发紧密关联。
为了解决fetch在非成功状态码下,不抛出异常的情况,umi-request会判断HTTP状态码是否为2xx;如果不是,则会抛出异常。并且对fetch自己抛出的异常也进行了处理,加上了更多信息,便于后续的处理。
/src/middleware/parseResponse.js
... .then(body => { ... if (copy.status >= 200 && copy.status < 300) { // 提供源response, 以便自定义处理 if (getResponse) { ctx.res = { data: body, response: copy }; return; } ctx.res = body; return; } throw new ResponseError(copy, 'http error', body, req, 'HttpError'); }) .catch(e => { if (e instanceof RequestError || e instanceof ResponseError) { throw e; } // 对未知错误进行处理 const { req, res } = ctx; e.request = e.request || req; e.response = e.response || res; e.type = e.type || e.name; e.data = e.data || undefined; throw e; }); ...
参考资料:umi-request
@umijs/plugin-request则在umi-request上又进行了封装。umi-request提供了错误处理机制,@umijs/plugin-request则提供了常规的错误处理方法,并约定了服务器返回响应的数据格式。还提供了useRequest。
需要特别注意的是,引用request时,要引用@umijs/plugin-request,而不是umi-request,否则会发现request的行为与@umijs/plugin-request文档描述的不一致。具体代码如下:
// 引用 umi-request 的 request。错误!!! import request from 'umi-request'; // 引用 @umijs/plugin-request 的 reqeust。正确。 import {request} from 'umi';
约定服务器返回的数据格式如下:
interface ErrorInfoStructure { success: boolean; // if request is success data?: any; // response data errorCode?: string; // code for errorType errorMessage?: string; // message display to user showType?: number; // error display type: 0 silent; 1 message.warn; 2 message.error; 4 notification; 9 page traceId?: string; // Convenient for back-end Troubleshooting: unique request ID host?: string; // onvenient for backend Troubleshooting: host of current access server }
对于服务器返回的数据于这个格式不一致的,可以在Ant Design Pro 5/src/app.tsx通过配置进行适配。但此适配只作用于错误处理,并影响接口返回的数据。所以在使用useRequest时,这个适配并没有用。
export const request: RequestConfig = { errorConfig: { adaptor: (resData) => { return { ...resData, success: resData.ok, errorMessage: resData.message, }; }, }, };
返回的数据格式中有success字段,用于描述请求是否成功。而umi-request对于http 2xx以外的响应都会抛出异常,此处的success又有何用呢?答案是http 2xx的请求也可以返回success:false从而人为的抛出一个异常。
但我们并不建议这样做,错误的请求应该返回http 2xx以外的响应,由umi-request自动抛出一个异常。所以适配数据结构时,success可始终为true。
/umijs/plugins/blob/master/packages/plugin-request/src/request.ts
... const errorAdaptor = requestConfig.errorConfig?.adaptor || (resData => resData); ... // 中间件统一错误处理 // 后端返回格式 { success: boolean, data: any } // 按照项目具体情况修改该部分逻辑 requestMethodInstance.use(async (ctx, next) => { ... const errorInfo = errorAdaptor(resData, ctx); if (errorInfo.success === false) { // 抛出错误到 errorHandler 中处理 const error: RequestError = new Error(errorInfo.errorMessage); error.name = 'BizError'; error.data = resData; error.info = errorInfo; throw error; } });
如服务器按照格式返回数据,则一切较为顺利。但即使是正常的响应,也必须把数据包装在data字段里,这样在后端和前端都会感觉有些别扭。一般希望正常响应直接返回数据,只有在发生错误是,才返回类似的数据格式。
错误处理时,也会调用上述的数据格式适配,所以并不是success不为false数据适配就无用了。主要从数据适配里获得showType errorMessage errorCode。
/umijs/plugins/blob/master/packages/plugin-request/src/request.ts
const errorAdaptor = requestConfig.errorConfig?.adaptor || (resData => resData); requestMethodInstance = extend({ errorHandler: (error: RequestError) => { // @ts-ignore if (error?.request?.options?.skipErrorHandler) { throw error; } let errorInfo: ErrorInfoStructure | undefined; if (error.name === 'ResponseError' && error.data && error.request) { const ctx: Context = { req: error.request, res: error.response, }; errorInfo = errorAdaptor(error.data, ctx); error.message = errorInfo?.errorMessage || error.message; error.data = error.data; error.info = errorInfo; } errorInfo = error.info; if (errorInfo) { const errorMessage = errorInfo?.errorMessage; const errorCode = errorInfo?.errorCode; const errorPage = requestConfig.errorConfig?.errorPage || DEFAULT_ERROR_PAGE; switch (errorInfo?.showType) { case ErrorShowType.SILENT: // do nothing break; case ErrorShowType.WARN_MESSAGE: message.warn(errorMessage); break; case ErrorShowType.ERROR_MESSAGE: message.error(errorMessage); break; case ErrorShowType.NOTIFICATION: notification.open({ message: errorMessage, }); break; case ErrorShowType.REDIRECT: // @ts-ignore history.push({ pathname: errorPage, query: { errorCode, errorMessage }, }); // redirect to error page break; default: message.error(errorMessage); break; } } else { message.error(error.message || 'Request error, please retry.'); } throw error; }, ...requestConfig, });
数据类型中showType字段的值有以下几个,配合错误处理方法,可以针对不同错误类型以不同的方式显示。
export enum ErrorShowType { SILENT = 0, // 不提示错误 WARN_MESSAGE = 1, // 警告信息提示 ERROR_MESSAGE = 2, // 错误信息提示 NOTIFICATION = 4, // 通知提示 REDIRECT = 9, // 页面跳转 }
安装前面的数据格式约定,useRequest默认从响应数据里的data字段里获取数据。如果服务器端是直接返回数据,则需要在Ant Design Pro/config/config.ts配置:
request: { dataField: '', }
需要注意,前面做的数据适配在useRequest里是无效的,不要认为做了数据适配就万事大吉了。当然服务器按照前面约定的数据格式返回数据就没这些烦恼了。
Ant Design对分页数据的结构也有规定。
{ list: [], current?: number, pageSize?: number, total?: number, }
如不符合这个格式,可以在useRequest的formatResult进行配置。如:
const { data, loading } = useRequest(() => { return services.getUserList('/api/test'); },{ formatResult: (result) => { return ... } });
参考资料:
@umijs/plugin-request文档
@umijs/plugin-request源码
提供了自定义错误处理方法,和自定义数据格式的接口。默认的演示代码中,覆盖了@umijs/plugin-request的错误处理方法。如未注意到这点,则会迷惑于Ant Design Pro 5的错误处理行为与@umijs/plugin-request文档描述的并不一致,前面所述的错误显示类型完全无效。
Ant Design Pro/config/config.ts
const errorHandler = (error: ResponseError) => { const { response } = error; if (response && response.status) { const errorText = codeMessage[response.status] || response.statusText; const { status, url } = response; notification.error({ message: `请求错误 ${status}: ${url}`, description: errorText, }); } if (!response) { notification.error({ description: '您的网络发生异常,无法连接服务器', message: '网络异常', }); } throw error; }; export const request: RequestConfig = { errorHandler, };
上述内容就是Ant Design Pro 5 网络请求和错误处理是怎样的,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。