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 管理,便于维护
  • 可扩展性 - 支持自定义拦截器和配置
相关推荐
fhsWar2 小时前
Vue3 props: `required: true` 与 vant 的`makeRequiredProp`
前端·javascript·vue.js
开发者小天3 小时前
uniapp中对接开发激励广告视频
uni-app
奎歪歪3 小时前
UniApp缓存系统详解
缓存·uni-app·1024程序员节
2501_915106325 小时前
iOS 打包 IPA 全流程详解,签名配置、工具选择与跨平台上传实战指南
android·macos·ios·小程序·uni-app·cocoa·iphone
00后程序员张6 小时前
iOS 混淆实操指南多工具组合实现 IPA 混淆、加固与发布治理 IPA 加固
android·ios·小程序·https·uni-app·iphone·webview
阿珊和她的猫12 小时前
深入剖析 Vue Router History 路由刷新页面 404 问题:原因与解决之道
前端·javascript·vue.js
麦麦大数据20 小时前
F032 材料科学文献知识图谱可视化分析系统(四种知识图谱可视化布局) | vue + flask + echarts + d3.js 实现
vue.js·flask·知识图谱·数据可视化·论文文献·1024程序员节·科研图谱
web打印社区21 小时前
使用React如何静默打印页面:完整的前端打印解决方案
前端·javascript·vue.js·react.js·pdf·1024程序员节
小光学长21 小时前
基于Vue的课程达成度分析系统t84pzgwk(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
前端·数据库·vue.js
麦麦大数据1 天前
F033 vue+neo4j图书智能问答+知识图谱推荐系统 |知识图谱+neo4j+vue+flask+mysql实现代码
vue.js·flask·nlp·neo4j·智能问答·图书·1024程序员节