当前位置: 首页 > news >正文

解决uni-app通用上传与后端接口不匹配问题:原生上传文件方法封装 ✨

在 uni-app 开发中,文件上传是高频需求 📤。 uni-app自带的uni.uploadFile虽便捷,但面对后端接口的个性化要求时,常因参数格式、请求头限制等问题 “卡壳”。今天就分享一个我封装的原生上传方法,完美解决接口不匹配问题,还附带详细使用指南哦!
在这里插入图片描述

一、方法背景 📝

最近项目中,后端接口提出了 3 个 “特殊要求”:

  1. 业务数据需以 Blob类型的 JSON 格式 传递 📦;

  2. 请求头必须携带自定义的 RequestId加密字段 🔑;

  3. 需实时展示文件上传进度 📊。

uni.uploadFile在「参数格式转换」和「自定义请求头」上存在局限,无法直接满足需求。因此,基于XMLHttpRequestFormData封装了这个原生上传方法,一次性解决所有痛点!

二、封装的上传文件方法代码 🚀

// 引入基础地址和获取加密RequestId的方法import { BASE_URL } from '@/config/requestConfig';import { getEncrypted } from '@/utils/encryptionUtil';// 自定义文件上传方法(解决uni.uploadFile接口不匹配问题)// @param {Object} formDatas - 业务相关的参数数据(如作品名称、作者信息)// @param {Array} files - 待上传文件数组(每个文件需含name和data属性)// @returns {Promise} - 成功resolve结果,失败reject错误export const upLoadWorks = (formDatas, files) => {return new Promise(async (resolve, reject) => {// 1. 拼接完整上传接口地址(需替换为你的实际接口)const url = BASE_URL + '/auth/upload';// 2. 创建FormData承载参数和文件(核心容器)const formData = new FormData();// 🌟 关键:将业务参数转为Blob类型JSON(后端要求的格式)formData.append('teamWorksCustom', new Blob([JSON.stringify(formDatas)], {type: "application/json"}));// 🌟 关键:遍历文件数组,添加到FormData(支持多文件上传)files.map(file => {formData.append(file.name, file.data);});// 3. 初始化XMLHttpRequest(原生AJAX核心)const xhr = new XMLHttpRequest();xhr.open('POST', url, true); // 异步POST请求// 🌟 关键:设置自定义请求头(后端要求的RequestId)xhr.setRequestHeader('RequestId', await getEncrypted());// 🌟 关键:监听上传进度(实时展示给用户)xhr.upload.onprogress = function(event) {if (event.lengthComputable) {// 计算上传进度百分比let percentComplete = event.loaded / event.total;// 显示进度loading(提升用户体验)uni.showLoading({title: '已上传' + Math.floor((percentComplete * 100)) + '%',mask: true});} else {console.log('无法计算进度 📈');}};// 4. 处理请求结果xhr.onload = function() {uni.hideLoading(); // 关闭loading(无论成败都要关!)if (xhr.status === 200) {// 成功:解析JSON响应并返回resolve(JSON.parse(xhr.responseText));} else {// 失败:返回状态码(便于排查问题)reject(xhr.status);}};// 5. 处理请求错误(如网络异常)xhr.onerror = function(err) {uni.hideLoading();reject(err);console.error('请求出错 ❌', err);};// 6. 发送请求(核心步骤)xhr.send(formData);});};

三、方法解析 🔍

1. 核心参数说明

参数名类型作用注意事项
formDatasObject业务参数(如作品名、作者)必须转为Blob类型 JSON,否则后端无法解析!
filesArray待上传文件数组每个文件需含 name(后端字段名)data(文件原始数据)

2. 3 个核心逻辑(必看!)

  • 📦 FormData 构建:用FormData统一承载 “Blob 类型业务参数” 和 “文件数据”,契合后端接口的参数格式要求;

  • 🔑 自定义请求头:通过xhr.setRequestHeader添加RequestId,解决uni.uploadFile无法灵活设置请求头的问题;

  • 📊 进度监听xhr.upload.onprogress实时计算进度,搭配uni.showLoading让用户清晰感知上传状态,避免 “卡顿时误以为没反应”。

四、使用场景(精准匹配!)🎯

以下场景用这个方法,效率直接拉满:

  1. 后端要求特殊参数格式 📋:比如业务参数需Blob类型 JSON、多参数嵌套等,uni.uploadFile搞不定的情况;

  2. 需要自定义请求头 🔒:比如接口要求携带TokenRequestId等自定义字段,且需加密处理;

  3. 大文件上传需进度展示 📁:如视频、压缩包等大文件,进度条能极大提升用户体验;

  4. uni.uploadFile无法满足的其他场景 ❌:比如后端接口是 RESTful 风格、需自定义响应解析逻辑等。

五、适用的后台接口类型 🖥️

你的后端接口需满足以下 4 个条件,才能完美适配这个方法:

  1. ✅ 支持FormData 格式请求体:能解析FormData中的 “Blob 参数” 和 “文件数据”;

  2. ✅ 能识别自定义请求头:能读取并验证RequestId等自定义字段;

  3. ✅ 返回JSON 格式响应:方法会自动解析 JSON,若后端返回其他格式(如 XML)需修改resolve逻辑;

  4. ✅ 支持多文件上传:能根据file.name(前端传的字段名)分别接收多个文件。

六、使用步骤(手把手教学!)📝

1. 准备依赖(先做这步!)

确保项目中已引入 2 个关键依赖:

  • BASE_URL:接口基础地址(如https://api.xxx.com);

  • getEncrypted():异步获取加密RequestId的方法(若后端不需要,可删除请求头相关代码)。

2. 3 步调用上传方法

(1)选择文件并转成 “文件数据”

用 Uniapp 的uni.chooseImage/uni.chooseVideo选文件,再通过uni.getFileSystemManager()将 “临时路径” 转成 “原始文件数据”:

// 选择图片示例(支持多选)uni.chooseImage({count: 3, // 最多选3张sizeType: ['original', 'compressed'], // 原图/压缩图sourceType: ['album', 'camera'], // 相册/相机success: async (res) => {const tempFilePaths = res.tempFilePaths;const files = [];// 遍历临时路径,转成文件数据for (let i = 0; i < tempFilePaths.length; i++) {const tempFilePath = tempFilePaths[i];// 读取文件数据(关键步骤!)const fileData = await new Promise((resolve) => {uni.getFileSystemManager().readFile({filePath: tempFilePath,success: (fileRes) => {resolve(fileRes.data); // 拿到原始文件数据}});});// 添加到files数组(name要和后端字段名一致!)files.push({name: `image${i + 1}`, // 后端接收字段名,如image1、image2data: fileData});}// 调用上传方法(下一步讲)await uploadFiles(files);}});
(2)准备业务参数
// 示例:业务参数(根据你的实际需求修改)const formDatas = {workName: '我的旅行vlog', // 作品名author: '小明', // 作者teamId: 'team_123456', // 团队ID// 其他参数...};
(3)调用方法并处理结果
import { upLoadWorks } from '@/utils/uploadUtil'; // 引入方法async function uploadFiles(files) {try {const formDatas = { workName: '我的旅行vlog', author: '小明' };// 调用上传方法const uploadResult = await upLoadWorks(formDatas, files);// 成功:提示+后续操作(如跳转页面)uni.showToast({ title: '上传成功 ✅', icon: 'success' });console.log('上传结果:', uploadResult);// 跳转页面示例:uni.navigateTo({ url: '/pages/success/success' });} catch (err) {// 失败:提示用户+记录错误(便于排查)uni.showToast({ title: '上传失败 ❌', icon: 'none' });console.error('上传错误:', err);}}

七、注意事项(避坑指南!)⚠️

  1. 📁 文件数据必须转对:如果直接传 “临时文件路径”(如res.tempFilePaths),会导致上传失败!必须用uni.getFileSystemManager().readFile转成原始文件数据;

  2. 🔑 RequestId 要有效getEncrypted()必须返回后端认可的加密值,否则会被接口拦截(若不需要,直接删除xhr.setRequestHeader这行);

  3. 📍 接口地址要改对url = BASE_URL + '/auth/upload'中的/auth/upload是示例接口,一定要替换成你的实际接口路径;

  4. 📱 兼容性测试:该方法用了XMLHttpRequestFormData,在 Uniapp 的 H5、App 端基本没问题,但低版本小程序可能有兼容问题,上线前务必多端测试;

  5. 🚨 loading 必须关闭xhr.onloadxhr.onerror中都要加uni.hideLoading(),否则会出现 “loading 一直转” 的尴尬情况!

八、总结 📌

这个原生上传方法的核心价值,在于突破了 Uniapp 通用方法的限制,精准匹配后端接口的个性化需求。无论是 “特殊参数格式”“自定义请求头”,还是 “进度展示”,都能一站式解决。

实际开发中,你可以根据后端接口的变化灵活调整:比如不需要RequestId就删请求头代码,后端返回非 JSON 就修改resolve的解析逻辑。希望这个方法能帮你少踩坑,高效完成文件上传功能!

如果有疑问或优化建议,欢迎在评论区交流哦~ 💬

http://www.dtcms.com/a/540544.html

相关文章:

  • 管廊建设网站线上推广网络公司
  • 汽车交互式系统专利拆解:VR/AR 画面生成与挡风玻璃异步转换的流畅性测试
  • Python爬虫实战:中信标普 50 指数数据获取与趋势分析
  • 浦江网站建设站酷app
  • 什么是技术架构、数据架构、业务架构、应用架构、产品架构和项目架构?
  • LLaMA-Factory 集成了哪些超参数调优框架?及 Optuna + Weights Biases + TensorBoard对比分析
  • 【软考架构】案例分析:MongoDB 如何存储非结构化数据以及其矢量化存储的优点。
  • 网络共享总失败?先检查是否有计算机名冲突
  • 最好用的企业网站cms湘潭网站建设工作室
  • 在网站后台做网页河南省工程建设协会网站
  • 【k8s】Deployment、StatefulSet、DaemonSet
  • 优购物官方网站订单查询烟台建设科技网站
  • qrc机制——Qt
  • [尚硅谷-尚庭公寓0-90做了部分]
  • 外资企业可以在中国境内做网站吗自己做网站买东西
  • 百度脑图网站建设流程图php网站模板源码下载
  • TDengine 数学函数 SQRT 用户手册
  • 【Qt C++ QSerialPort】QSerialPort fQSerialPortInfo::availablePorts() 执行报错问题解决方案
  • 鸿蒙ArkUI布局与样式进阶(十四)——剩余参数 · 展开运算符 · 接口继承 · 接口实现 · 泛型全面讲解
  • 【# Python 离线安装:把 pip 源设为本地目录】
  • 在pycharm中install不上需要的包
  • 国外工业设计网站建站系统软件有哪些
  • 做网站毕业设计华建河北住房和城乡建设厅网站
  • 公司网站免费建站西安网站工作室
  • 20.13 ChatPPT v3.0多模态图像处理实战:突破93.2%准确率的技术揭秘
  • 回头看SSM项目的创建
  • 《赋能AI解锁Coze智能体搭建核心技能(1)--- 初识coze》
  • 大模型面试题:请讲一下GPT系列模型是如何演进的?
  • 分享5款软件让电脑更方便
  • 做网站建设公司赚钱浙江省建设厅网站地址