uni-app x 纯原生跨平台 APP 自定义 uni.request 预处理接口响应数据

uni.request 预处理接口响应数据

/**
 * 自定义请求封装的参数
 */
export type Options<T> {
	url : string
	data ?: any | null
	header ?: UTSJSONObject | null
	method ?: RequestMethod | null,
	timeout ?: number | null,
	/**
	 * 请求成功后、检查返回数据没有问题后 才执行
	 * 
	 * 1. 用于全局响应时数据正常时执行
	 */
	ok ?: (res : RequestSuccess<T>) => void
	/**
	 * 返回状态码、返回数据检查失败,自动执行
	 * 
	 * 1. 用于全局异常响应时弹窗提醒
	 */
	err ?: (res : RequestSuccess<T>) => void
	/**
	 * 请求失败后,自动执行
	 * 
	 * 1. 用于网络请求失败时弹窗提醒
	 * 2. 返回数据与范型不匹配(反序列化失败)
	 */
	fail ?: (res : RequestFail) => void
}

/**
 * 自定义请求封装
 */
export default function request<T>(ops : Options<T>) {
	uni.request<T>({
		url: ops.url,
		data: ops.data,
		header: ops.header,
		method: ops.method,
		timeout: ops.timeout,
		success(res : RequestSuccess<T>) {
			console.log(`${ops.url} success:`, res)

			// 将返回数据的范型对象处理为 JSON 字符串
			const dataStr = JSON.stringify(res.data)
			// 转为 JSON 对象
			const data = JSON.parse<UTSJSONObject>(dataStr)
			// 用于判断返回数据是否正常
			const error = data?.get('error')

			if (res.statusCode == 404) {
				// 处理接口不存在的情况
				uni.showToast({ title: `${ops.url} 接口不存在`, icon: 'none' })

				if (ops.err != null) {
					ops.err(res)
				}

			} else if (res.statusCode != 200) {
				// 状态码不正常

				if (res.data == null) {
					// 数据为空,弹窗显示返回数据为空
					uni.showToast({ title: `${ops.url} 接口状态码:${res.statusCode},返回数据为空`, icon: 'none' })

					if (ops.err != null) {
						ops.err(res)
					}

				} else {
					// 数据不为空,弹窗显示异常数据提示
					let title = (error == null || error == '') ? dataStr : error
					uni.showToast({ title: title as string, icon: 'none' })

					if (ops.err != null) {
						ops.err(res)
					}
				}
			} else {

				if (error != null || error == '') {
					// 数据异常(根据返回数据中如果存在 error 节点,则直接弹窗提示 error 信息)
					uni.showToast({ title: error as string, icon: 'none' })

					if (ops.err != null) {
						ops.err(res)
					}

				} else if (ops.ok != null) {
					// 数据正常,执行接口后续操作(如果存在后续操作)
					console.log('ok')
					ops.ok(res)
				}
			}
		},
		fail(err : RequestFail) {
			console.log(`${ops.url} fail:`, err)

			let message = err.cause?.message
			message = message == null ? JSON.stringify(err) : message

			uni.showToast({ title: message, icon: 'none' })

			if (ops.fail != null) {
				ops.fail(err)
			}
		}
	})
}

使用示例

export type LoginResponse = {
	timestamp : string | null
	status : number | null
	error : string | null
	path : string | null

	redirectUri : string | null
	clientId : string | null
	scope : string | null
}

request<LoginResponse>({
	url: `http://172.25.25.24:51234/login`,
	method: 'POST',
	header: { 'Content-Type': 'application/x-www-form-urlencoded' },
	data: {
		username: username.value,
		password: password.value,
	},
	ok(res : RequestSuccess<LoginResponse>) {
		console.log('正常登录结果:', res)
	},
	err: (res: RequestSuccess<LoginResponse>) => {
		console.log('异常登录结果:', res)
	},
	fail: (err : RequestFail) {
		// 如:网络异常、返回数据反序列化异常
		console.log('失败登录结果:', err)
	}
})