uniapp 请求接口封装和使用

1. 基础请求封装

javascript 复制代码
// utils/request.js
// 请求基础配置
const BASE_URL = 'http://localhost:90'; // 后端服务IP和端口

// 请求拦截器
const requestInterceptor = {
	invoke(options) {
		// 添加 token 等全局参数
		const token = uni.getStorageSync('token')
		if (token) {
			options.header = {
				...options.header,
				'Authorization': `Bearer ${token}`
			}
		}

		// 显示加载提示
		if (options.loading !== false) {
			uni.showLoading({
				title: options.loadingText || '加载中...',
				mask: true
			})
		}

		return options
	}
}

// 响应拦截器
const responseInterceptor = {
	success: (res) => {
		// 隐藏加载提示
		uni.hideLoading()
		const {
			statusCode,
			data
		} = res
		console.log("responseInterceptor success", data);
		if (statusCode === 200) {
			// 根据后端返回结构进行调整
			if (data.code === 200 || data.success) {
				return Promise.resolve(data)
			} else {
				// 业务错误
				uni.showToast({
					title: data.message || data.msg || '请求失败',
					icon: 'none'
				})
				return Promise.reject(data)
			}
		} else {
			// HTTP 错误
			handleHttpError(statusCode)
			return Promise.reject(res)
		}
	},

	fail: (error) => {
		console.log("responseInterceptor error", error);
		uni.hideLoading()
		handleNetworkError(error)
		return Promise.reject(error)
	}
}

// 处理 HTTP 错误
function handleHttpError(statusCode) {
	const errorMap = {
		400: '请求错误',
		401: '未授权,请重新登录',
		403: '拒绝访问',
		404: '请求地址不存在',
		500: '服务器内部错误',
		502: '网关错误',
		503: '服务不可用'
	}

	const message = errorMap[statusCode] || `网络请求错误 (${statusCode})`
	uni.showToast({
		title: message,
		icon: 'none'
	})
}

// 处理网络错误
function handleNetworkError(error) {
	let message = '网络连接失败'

	if (error.errMsg && error.errMsg.includes('timeout')) {
		message = '网络请求超时'
	} else if (error.errMsg && error.errMsg.includes('fail')) {
		message = '网络连接失败,请检查网络'
	}

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

// 核心请求方法
function request(options) {
	// 合并配置
	const config = {
		url: options.url.startsWith('http') ? options.url : `${BASE_URL}${options.url}`,
		method: options.method || 'GET',
		data: options.data || {},
		header: options.header || {},
		timeout: options.timeout || 10000,
		loading: options.loading !== false,
		loadingText: options.loadingText || '加载中...'
	}

	// 执行请求拦截器
	const finalOptions = requestInterceptor.invoke(config)

	return new Promise((resolve, reject) => {
		uni.request({
			...finalOptions,
			success: (res) => {
				responseInterceptor.success(res)
					.then(resolve)
					.catch(reject)
			},
			fail: (error) => {
				responseInterceptor.fail(error)
					.catch(reject)
			}
		})
	})
}

// 快捷方法
const http = {
	get(url, data = {}, options = {}) {
		return request({
			url,
			data,
			method: 'GET',
			...options
		})
	},

	post(url, data = {}, options = {}) {
		return request({
			url,
			data,
			method: 'POST',
			...options
		})
	},

	put(url, data = {}, options = {}) {
		return request({
			url,
			data,
			method: 'PUT',
			...options
		})
	},

	delete(url, data = {}, options = {}) {
		return request({
			url,
			data,
			method: 'DELETE',
			...options
		})
	},

	upload(url, filePath, formData = {}, options = {}) {
		return new Promise((resolve, reject) => {
			uni.uploadFile({
				url: `${BASE_URL}${url}`,
				filePath,
				name: options.name || 'file',
				formData,
				header: {
					'Authorization': `Bearer ${uni.getStorageSync('token')}`,
					...options.header
				},
				success: (res) => {
					if (res.statusCode === 200) {
						const data = JSON.parse(res.data)
						resolve(data)
					} else {
						reject(res)
					}
				},
				fail: reject
			})
		})
	}
}
export default http

2. API 接口统一管理

javascript 复制代码
// 引入 request 文件
import http from '@/utils/request';

// 检测版本是否更新
export function checkAppVersion(params) {
	return http.get('/demo', params)
}

3. 页面使用(VUE3写法)

javascript 复制代码
// app.vue
<script setup>
	import {
		onLaunch
	} from '@dcloudio/uni-app'

	import {
		checkAppVersion
	} from "@/api/upgrade.js";

	// 只能在App.vue里监听应用的生命周期,在其它页面监听无效
	onLaunch(() => {
		checkVersionUpdate();
	})
	const checkVersionUpdate = () => {
		// #ifdef APP-PLUS
		const systemInfo = uni.getSystemInfoSync(); // manifest.json 中的相关版本信息 
		console.log("当前版本信息", systemInfo);
		// #endif
		const params = {
			version: systemInfo.appVersion, // 当前版本号
		};
		// 检测版本是否更新
		checkAppVersion(params).then(res => {
			// 逻辑代码
		}).catch(err => {
			console.log("err", err);
		})
	}
</script>

总结:

  • 统一的错误处理 - 自动处理网络错误和业务错误
  • 自动添加 Token - 请求时自动携带认证信息
  • 加载状态管理 - 可配置的加载提示
  • 快捷方法 - 提供 GET、POST、PUT、DELETE 等快捷方式
  • 文件上传 - 封装了文件上传功能
  • 类型安全 - 统一的 API 管理,便于维护
  • 可扩展性 - 支持自定义拦截器和配置
相关推荐
岁月宁静3 小时前
🎨 打造 AI 应用的 “门面”:Vue3.5 + MarkdownIt 实现高颜值、高性能的答案美化组件
前端·javascript·vue.js
码农飞哥3 小时前
AI编程开发系统001-基于SpringBoot+Vue的旅游民宿租赁系统
vue.js·spring boot·毕业设计·ai编程·计算机源码
光影少年3 小时前
vue3新增哪些内容以及api更改了哪些
前端·vue.js·掘金·日新计划
肥喵蒙太奇5 小时前
uniapp 使用towxml
uni-app
小高0075 小时前
前端如何优雅地生成唯一标识?——一份跨环境 UUID 工具函数的封装与实战
前端·javascript·vue.js
我是日安5 小时前
从零到一打造 Vue3 响应式系统 Day 24 - Watch:Options
前端·javascript·vue.js
吹晚风吧5 小时前
什么是跨域?跨域怎么解决?跨域解决的是什么问题?
java·vue.js·js·cors
小*-^-*九9 小时前
Electron vue项目 打包 exe文件
javascript·vue.js·electron
Nan_Shu_61416 小时前
学习:uniapp全栈微信小程序vue3后台-额外/精彩报错篇
前端·学习·微信小程序·小程序·uni-app·notepad++