<返回目录     Powered by claud/xia兄

第8课:网络请求

深入理解UniApp数据交互与API调用

📚 课程概述

网络请求是现代应用开发的核心功能,用于与后端API进行数据交互。本课程将深入讲解UniApp的网络请求机制,包括uni.request、文件上传下载、请求封装、错误处理等,帮助你构建稳定可靠的数据交互系统。

学习目标:

🌐 什么是网络请求?

网络请求的概念

网络请求是指客户端(前端应用)向服务器发送请求,获取或提交数据的过程。UniApp提供了统一的网络请求API,支持跨平台使用。

网络请求流程:

前端应用 → 发送请求 → 服务器处理 → 返回响应 → 前端处理数据

HTTP请求方法

📡 uni.request基础用法

基本请求

uni.request参数详解

参数 类型 必填 说明
url String 请求的接口地址
data Object/String 请求的参数
header Object 请求头
method String HTTP请求方法
timeout Number 超时时间,单位ms
dataType String 返回的数据类型
responseType String 响应的数据类型
success Function 成功回调函数
fail Function 失败回调函数
complete Function 完成回调函数

🔐 RESTful API设计

RESTful规范

RESTful是一种API设计风格,使用HTTP方法表示操作类型,使用URL表示资源:

// 获取用户列表 GET /api/users // 获取单个用户 GET /api/users/:id // 创建用户 POST /api/users // 更新用户 PUT /api/users/:id // 删除用户 DELETE /api/users/:id // 分页查询 GET /api/users?page=1&pageSize=10 // 条件查询 GET /api/users?status=active&role=admin

RESTful API封装

// api/user.js import request from '@/utils/request' export default { // 获取用户列表 getList(params) { return request({ url: '/users', method: 'GET', params }) }, // 获取用户详情 getDetail(id) { return request({ url: `/users/${id}`, method: 'GET' }) }, // 创建用户 create(data) { return request({ url: '/users', method: 'POST', data }) }, // 更新用户 update(id, data) { return request({ url: `/users/${id}`, method: 'PUT', data }) }, // 删除用户 delete(id) { return request({ url: `/users/${id}`, method: 'DELETE' }) } }

🛡️ 请求封装与拦截

创建请求封装

// utils/request.js const baseURL = 'https://api.example.com' function request(options) { return new Promise((resolve, reject) => { uni.request({ url: baseURL + options.url, method: options.method || 'GET', data: options.data || {}, header: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + getToken(), ...options.header }, timeout: options.timeout || 30000, dataType: options.dataType || 'json', success: (res) => { if (res.statusCode >= 200 && res.statusCode < 300) { resolve(res.data) } else { handleError(res) reject(res) } }, fail: (error) => { handleError(error) reject(error) }, complete: options.complete }) }) } function getToken() { return uni.getStorageSync('token') || '' } function handleError(error) { console.error('请求错误:', error) if (error.statusCode === 401) { uni.showToast({ title: '登录已过期,请重新登录', icon: 'none' }) uni.reLaunch({ url: '/pages/login/login' }) } else if (error.statusCode === 403) { uni.showToast({ title: '没有权限', icon: 'none' }) } else if (error.statusCode === 404) { uni.showToast({ title: '请求的资源不存在', icon: 'none' }) } else if (error.statusCode >= 500) { uni.showToast({ title: '服务器错误', icon: 'none' }) } else { uni.showToast({ title: '网络错误', icon: 'none' }) } } export default request

请求拦截器

// utils/request.js const requestQueue = [] let isRefreshing = false function request(options) { return new Promise((resolve, reject) => { // 请求拦截 const config = { url: baseURL + options.url, method: options.method || 'GET', data: options.data || {}, header: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + getToken(), ...options.header }, timeout: options.timeout || 30000, dataType: options.dataType || 'json', success: (res) => { // 响应拦截 if (res.statusCode >= 200 && res.statusCode < 300) { if (res.data.code === 200) { resolve(res.data.data) } else if (res.data.code === 401) { handleTokenExpired() reject(res.data) } else { uni.showToast({ title: res.data.message || '请求失败', icon: 'none' }) reject(res.data) } } else { handleError(res) reject(res) } }, fail: (error) => { handleError(error) reject(error) } } uni.request(config) }) } function handleTokenExpired() { if (isRefreshing) { return new Promise((resolve) => { requestQueue.push({ resolve }) }) } isRefreshing = true refreshToken().then(token => { uni.setStorageSync('token', token) requestQueue.forEach(item => item.resolve()) requestQueue.length = 0 isRefreshing = false }).catch(() => { requestQueue.length = 0 isRefreshing = false uni.reLaunch({ url: '/pages/login/login' }) }) } function refreshToken() { return uni.request({ url: baseURL + '/auth/refresh', method: 'POST', data: { refreshToken: uni.getStorageSync('refreshToken') } }) } export default request

📤 文件上传

uni.uploadFile

export default { data() { return { imageUrl: '' } }, methods: { chooseImage() { uni.chooseImage({ count: 1, sizeType: ['compressed'], sourceType: ['album', 'camera'], success: (res) => { const tempFilePaths = res.tempFilePaths this.uploadFile(tempFilePaths[0]) } }) }, uploadFile(filePath) { uni.showLoading({ title: '上传中...' }) uni.uploadFile({ url: 'https://api.example.com/upload', filePath: filePath, name: 'file', formData: { 'user': 'test' }, header: { 'Authorization': 'Bearer ' + getToken() }, success: (uploadFileRes) => { const data = JSON.parse(uploadFileRes.data) console.log('上传成功:', data) this.imageUrl = data.url uni.showToast({ title: '上传成功', icon: 'success' }) }, fail: (error) => { console.error('上传失败:', error) uni.showToast({ title: '上传失败', icon: 'none' }) }, complete: () => { uni.hideLoading() } }) } } }

📥 文件下载

uni.downloadFile

export default { methods: { downloadFile(url) { uni.showLoading({ title: '下载中...' }) const downloadTask = uni.downloadFile({ url: url, success: (res) => { if (res.statusCode === 200) { console.log('下载成功:', res.tempFilePath) // 保存文件 uni.saveFile({ tempFilePath: res.tempFilePath, success: (saveRes) => { console.log('保存成功:', saveRes.savedFilePath) uni.showToast({ title: '下载成功', icon: 'success' }) } }) } }, fail: (error) => { console.error('下载失败:', error) uni.showToast({ title: '下载失败', icon: 'none' }) }, complete: () => { uni.hideLoading() } }) // 监听下载进度 downloadTask.onProgressUpdate((res) => { console.log('下载进度:', res.progress + '%') console.log('已下载:', res.totalBytesWritten) console.log('总大小:', res.totalBytesExpectedToWrite) }) } } }

💡 最佳实践

性能优化建议:
常见问题:

🎯 实战案例:用户管理

🔮 下一步学习方向

掌握了网络请求后,下一课我们将深入学习数据存储,了解如何在本地存储和管理应用数据。