主要封装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;
}
}