主要封装uni-app网络中的请求以及上传、下载即 uni.request(OBJECT)、uni.uploadFile(OBJECT)和uni.downloadFile(OBJECT);
拦截器封装实现
请求拦截器
## interceptor.ts/*** 请求拦截* @param {RequestOption} options 请求配置* @param {boolean} hideLoading 是否打开 加载中 弹窗*/const reqInterceptor = async (options: RequestOption, hideLoading?: boolean) => {// 请求拦截时, 设置 header 的一些内容options.header = {// 设置默认的 header"Content-Type": "application/json;charset=UTF-8",...options.header,// 拦截到请求,设置需要的header处理};if(!hideLoading) {uni.showLoading({title: "正在加载..."});}return options;}
响应拦截器
## interceptor.ts/*** 响应拦截* @param {ResponseSuccess} response 响应返回的数据*/const resInterceptor = (response: ResponseSuccess) => {// 请求完成uni.hideLoading();const statusCode = response.statusCode as number;if(statusCode >= 200 && statusCode < 300) {// 日志收集let _result = null;if("data" in response) _result = response.data;if("tempFilePath" in response) _result = response.tempFilePath;return _result;} else if(statusCode === 500) {uni.showToast({icon: "none", title: "服务器错误"});// 日志收集return {wakaryReqReject: true,msg: "服务器错误",res: response}} else {uni.showToast({icon: "none", title: "服务器异常"});// 日志收集return {wakaryReqReject: true,msg: "服务器异常",res: response}}}
封装Request请求
Request具体实现
## request.ts/* 引用类型申明 */import { RequestMethod, RequestConfig, ResponseSuccess, ResponseFail, ResponseComplete, NewRequestOptions, RequestTask, UniRequestConfig } from 'request';import {reqInterceptor, resInterceptor} from './interceptor';import {RequestMethods, RequestType} from './requestEnum';const baseUrl:string = process.env.NODE_ENV === "development"?"http://test1.massmakers.cn":"线上地址";export default class Request {private _config: RequestConfig;private _requestInterceptor: Function | null;private _responseInterceptor: Function | null;private _success: Function | null;private _fail: Function | null;private _complete: Function | null;/*** 构造器* @param {RequestConfig} config 默认配置* @param {Function} callback 剩余参数--拦截器等*/constructor(config: RequestConfig, ...callback: Function[]) {this._config = config;this._config.baseUrl = this._config.baseUrl || baseUrl;[this._requestInterceptor=null, this._responseInterceptor=null, this._success=null,this._fail=null,this._complete=null] = callback;}/*** 请求 api* @param {RequestMethods} method 请求方式* @param {string} apiUrl 接口路径* @param {NewRequestOptions} options 请求剩余配置*/public async request(method: RequestMethods, apiUrl: string, params?: object, options?: NewRequestOptions):Promise<string | object> {// 处理请求配置let _config = await this.reqConfig(this._config, method, apiUrl, params, options);const _type = options?.type || RequestType.REQUEST;const _successHandler = options?.success || null, _failHandler = options?.fail || null, _completeHandler = options?.complete || null;if(!_config || typeof _config !== "object") {return Promise.reject('参数不正确');}// 处理结束return new Promise((resolve, reject) => {_config["success"] = (response: ResponseSuccess): void => {let _res = this._responseInterceptor?.(response) || null;_successHandler?.(response);if (_res?.wakaryReqReject) {delete _res.wakaryReqReject;reject(_res);} else {resolve(_res);}}_config["fail"] = (err: ResponseFail): void => {_failHandler?.(err);}_config["complete"] = (res: ResponseComplete): void => {_completeHandler?.(res);}switch(_type) {case RequestType.REQUEST:uni.request(_config);break;case RequestType.UPLOADFILE:uni.uploadFile(_config);break;case RequestType.DOWNLOADFILE:uni.uploadFile(_config);break;default:}});}/*** 处理请求配置* @param {RequestConfig} config 默认配置* @param {RequestMethods} method 请求方式* @param {string} apiUrl 接口路径* @param {NewRequestOptions} options 请求剩余配置*/private async reqConfig(config: RequestConfig, method: RequestMethods, apiUrl: string, params?: object, options?: NewRequestOptions):Promise<UniRequestConfig> {const regExp = /(http|https):\/\/([\w.]+\/?)\S*/;const _options = options || null, _type = _options?.type || RequestType.REQUEST, _hideLoading = _options?.hideLoading || false;let _data = _options && _options.data || null;let _config: UniRequestConfig = {url: regExp.test(apiUrl)?apiUrl: config.baseUrl + apiUrl,method,data: Object.assign({},params, _data)};try {_config = await this._requestInterceptor?.(Object.assign({},_options, _config), _hideLoading);} catch(e) {throw e;}switch(_type) {case RequestType.REQUEST:_config.dataType = _config.dataType || "json";_config.responseType = _config.responseType || "text";break;case RequestType.UPLOADFILE:delete _config.header["Content-Type"];delete _config.header["Referer"];break;case RequestType.DOWNLOADFILE:delete _config.header["Referer"];break;default:}return Promise.resolve(_config);}}
再次封装, 对象模式传递请求类型 method
## request.ts/*** js 中 this 作用域问题* for 循环遍历 实现 request.get 方式传参method*/const _this = new Request({},reqInterceptor,resInterceptor);const request: RequestMethod = {};for (let method in RequestMethods) {request[method.toLowerCase()] =(apiUrl: string, params?: object, options?: NewRequestOptions) => _this.request(method as RequestMethods,apiUrl, params, options);}export {request};
至此,request封装完成.
Tips:
- 原 uni-app 请求中 中断请求 未封装,需要使用中断处理的需要使用原uni-app请求;
附录:
请求封装中使用的枚举数据
export const enum RequestType {REQUEST = "request",UPLOADFILE = "upload",DOWNLOADFILE = "download"}export enum RequestMethods {GET = "GET",POST = "POST",PUT = "PUT",DELETE = "DELETE",CONNECT = "CONNECT",HEAD = "HEAD",OPTIONS = "OPTIONS",TRACE = "TRACE"}
请求封装中使用的类型申明 .d.ts (存放在根目录下的typings文件夹下)
declare module 'request' {import {RequestType} from '@/utils/request/requestEnum';export interface RequestMethod {[RequestMethods.GET]?: Function;[RequestMethods.POST]?: Function;[RequestMethods.PUT]?: Function;[RequestMethods.DELETE]?: Function;[RequestMethods.CONNECT]?: Function;[RequestMethods.HEAD]?: Function;[RequestMethods.OPTIONS]?: Function;[RequestMethods.TRACE]?: Function;[method: string]: Function;}export interface NewAddRequestOptions {hideLoading?: boolean;type?: RequestType;}export type RequestOption = UniApp.RequestOptions & UniApp.UploadFileOption & UniApp.DownloadFileOption;export type NewRequestOptions = NewAddRequestOptions & RequestOption;export type ResponseSuccess = UniApp.RequestSuccessCallbackResult | UniApp.UploadFileSuccessCallbackResult | UniApp.DownloadSuccessData;export type ResponseFail = UniApp.GeneralCallbackResult;export type ResponseComplete = UniApp.GeneralCallbackResult;export type RequestTask = UniApp.RequestTask | UniApp.UploadTask | UniApp.DownloadTask | null;export interface RequestConfig {baseUrl?: string;}}
