主要封装uni-app网络中的请求以及上传、下载即 uni.request(OBJECT)、uni.uploadFile(OBJECT)和uni.downloadFile(OBJECT);

拦截器封装实现

请求拦截器

  1. ## interceptor.ts
  2. /**
  3. * 请求拦截
  4. * @param {RequestOption} options 请求配置
  5. * @param {boolean} hideLoading 是否打开 加载中 弹窗
  6. */
  7. const reqInterceptor = async (options: RequestOption, hideLoading?: boolean) => {
  8. // 请求拦截时, 设置 header 的一些内容
  9. options.header = {
  10. // 设置默认的 header
  11. "Content-Type": "application/json;charset=UTF-8",
  12. ...options.header,
  13. // 拦截到请求,设置需要的header处理
  14. };
  15. if(!hideLoading) {
  16. uni.showLoading({title: "正在加载..."});
  17. }
  18. return options;
  19. }

响应拦截器

  1. ## interceptor.ts
  2. /**
  3. * 响应拦截
  4. * @param {ResponseSuccess} response 响应返回的数据
  5. */
  6. const resInterceptor = (response: ResponseSuccess) => {
  7. // 请求完成
  8. uni.hideLoading();
  9. const statusCode = response.statusCode as number;
  10. if(statusCode >= 200 && statusCode < 300) {
  11. // 日志收集
  12. let _result = null;
  13. if("data" in response) _result = response.data;
  14. if("tempFilePath" in response) _result = response.tempFilePath;
  15. return _result;
  16. } else if(statusCode === 500) {
  17. uni.showToast({icon: "none", title: "服务器错误"});
  18. // 日志收集
  19. return {
  20. wakaryReqReject: true,
  21. msg: "服务器错误",
  22. res: response
  23. }
  24. } else {
  25. uni.showToast({icon: "none", title: "服务器异常"});
  26. // 日志收集
  27. return {
  28. wakaryReqReject: true,
  29. msg: "服务器异常",
  30. res: response
  31. }
  32. }
  33. }

封装Request请求

Request具体实现

  1. ## request.ts
  2. /* 引用类型申明 */
  3. import { RequestMethod, RequestConfig, ResponseSuccess, ResponseFail, ResponseComplete, NewRequestOptions, RequestTask, UniRequestConfig } from 'request';
  4. import {reqInterceptor, resInterceptor} from './interceptor';
  5. import {RequestMethods, RequestType} from './requestEnum';
  6. const baseUrl:string = process.env.NODE_ENV === "development"?"http://test1.massmakers.cn":"线上地址";
  7. export default class Request {
  8. private _config: RequestConfig;
  9. private _requestInterceptor: Function | null;
  10. private _responseInterceptor: Function | null;
  11. private _success: Function | null;
  12. private _fail: Function | null;
  13. private _complete: Function | null;
  14. /**
  15. * 构造器
  16. * @param {RequestConfig} config 默认配置
  17. * @param {Function} callback 剩余参数--拦截器等
  18. */
  19. constructor(config: RequestConfig, ...callback: Function[]) {
  20. this._config = config;
  21. this._config.baseUrl = this._config.baseUrl || baseUrl;
  22. [this._requestInterceptor=null, this._responseInterceptor=null, this._success=null,this._fail=null,this._complete=null] = callback;
  23. }
  24. /**
  25. * 请求 api
  26. * @param {RequestMethods} method 请求方式
  27. * @param {string} apiUrl 接口路径
  28. * @param {NewRequestOptions} options 请求剩余配置
  29. */
  30. public async request(method: RequestMethods, apiUrl: string, params?: object, options?: NewRequestOptions):Promise<string | object> {
  31. // 处理请求配置
  32. let _config = await this.reqConfig(this._config, method, apiUrl, params, options);
  33. const _type = options?.type || RequestType.REQUEST;
  34. const _successHandler = options?.success || null, _failHandler = options?.fail || null, _completeHandler = options?.complete || null;
  35. if(!_config || typeof _config !== "object") {
  36. return Promise.reject('参数不正确');
  37. }
  38. // 处理结束
  39. return new Promise((resolve, reject) => {
  40. _config["success"] = (response: ResponseSuccess): void => {
  41. let _res = this._responseInterceptor?.(response) || null;
  42. _successHandler?.(response);
  43. if (_res?.wakaryReqReject) {
  44. delete _res.wakaryReqReject;
  45. reject(_res);
  46. } else {
  47. resolve(_res);
  48. }
  49. }
  50. _config["fail"] = (err: ResponseFail): void => {
  51. _failHandler?.(err);
  52. }
  53. _config["complete"] = (res: ResponseComplete): void => {
  54. _completeHandler?.(res);
  55. }
  56. switch(_type) {
  57. case RequestType.REQUEST:
  58. uni.request(_config);
  59. break;
  60. case RequestType.UPLOADFILE:
  61. uni.uploadFile(_config);
  62. break;
  63. case RequestType.DOWNLOADFILE:
  64. uni.uploadFile(_config);
  65. break;
  66. default:
  67. }
  68. });
  69. }
  70. /**
  71. * 处理请求配置
  72. * @param {RequestConfig} config 默认配置
  73. * @param {RequestMethods} method 请求方式
  74. * @param {string} apiUrl 接口路径
  75. * @param {NewRequestOptions} options 请求剩余配置
  76. */
  77. private async reqConfig(config: RequestConfig, method: RequestMethods, apiUrl: string, params?: object, options?: NewRequestOptions):Promise<UniRequestConfig> {
  78. const regExp = /(http|https):\/\/([\w.]+\/?)\S*/;
  79. const _options = options || null, _type = _options?.type || RequestType.REQUEST, _hideLoading = _options?.hideLoading || false;
  80. let _data = _options && _options.data || null;
  81. let _config: UniRequestConfig = {
  82. url: regExp.test(apiUrl)?apiUrl: config.baseUrl + apiUrl,
  83. method,
  84. data: Object.assign({},params, _data)
  85. };
  86. try {
  87. _config = await this._requestInterceptor?.(Object.assign({},_options, _config), _hideLoading);
  88. } catch(e) {
  89. throw e;
  90. }
  91. switch(_type) {
  92. case RequestType.REQUEST:
  93. _config.dataType = _config.dataType || "json";
  94. _config.responseType = _config.responseType || "text";
  95. break;
  96. case RequestType.UPLOADFILE:
  97. delete _config.header["Content-Type"];
  98. delete _config.header["Referer"];
  99. break;
  100. case RequestType.DOWNLOADFILE:
  101. delete _config.header["Referer"];
  102. break;
  103. default:
  104. }
  105. return Promise.resolve(_config);
  106. }
  107. }

再次封装, 对象模式传递请求类型 method

  1. ## request.ts
  2. /**
  3. * js 中 this 作用域问题
  4. * for 循环遍历 实现 request.get 方式传参method
  5. */
  6. const _this = new Request({},reqInterceptor,resInterceptor);
  7. const request: RequestMethod = {};
  8. for (let method in RequestMethods) {
  9. request[method.toLowerCase()] =(apiUrl: string, params?: object, options?: NewRequestOptions) => _this.request(method as RequestMethods,apiUrl, params, options);
  10. }
  11. export {request};

至此,request封装完成.

Tips:

  • 原 uni-app 请求中 中断请求 未封装,需要使用中断处理的需要使用原uni-app请求;

附录:

请求封装中使用的枚举数据

  1. export const enum RequestType {
  2. REQUEST = "request",
  3. UPLOADFILE = "upload",
  4. DOWNLOADFILE = "download"
  5. }
  6. export enum RequestMethods {
  7. GET = "GET",
  8. POST = "POST",
  9. PUT = "PUT",
  10. DELETE = "DELETE",
  11. CONNECT = "CONNECT",
  12. HEAD = "HEAD",
  13. OPTIONS = "OPTIONS",
  14. TRACE = "TRACE"
  15. }

请求封装中使用的类型申明 .d.ts (存放在根目录下的typings文件夹下)

  1. declare module 'request' {
  2. import {RequestType} from '@/utils/request/requestEnum';
  3. export interface RequestMethod {
  4. [RequestMethods.GET]?: Function;
  5. [RequestMethods.POST]?: Function;
  6. [RequestMethods.PUT]?: Function;
  7. [RequestMethods.DELETE]?: Function;
  8. [RequestMethods.CONNECT]?: Function;
  9. [RequestMethods.HEAD]?: Function;
  10. [RequestMethods.OPTIONS]?: Function;
  11. [RequestMethods.TRACE]?: Function;
  12. [method: string]: Function;
  13. }
  14. export interface NewAddRequestOptions {
  15. hideLoading?: boolean;
  16. type?: RequestType;
  17. }
  18. export type RequestOption = UniApp.RequestOptions & UniApp.UploadFileOption & UniApp.DownloadFileOption;
  19. export type NewRequestOptions = NewAddRequestOptions & RequestOption;
  20. export type ResponseSuccess = UniApp.RequestSuccessCallbackResult | UniApp.UploadFileSuccessCallbackResult | UniApp.DownloadSuccessData;
  21. export type ResponseFail = UniApp.GeneralCallbackResult;
  22. export type ResponseComplete = UniApp.GeneralCallbackResult;
  23. export type RequestTask = UniApp.RequestTask | UniApp.UploadTask | UniApp.DownloadTask | null;
  24. export interface RequestConfig {
  25. baseUrl?: string;
  26. }
  27. }

参考资料

uni-app官方文档之网络