UniApp Base64上传终极解决方案

在 UniApp 中,uni.uploadFile API 通常需要一个本地文件路径 (filePath),而不能直接上传 Base64 字符串。因此,核心思路分为两步:

  1. 转存:将 Base64 字符串写入本地临时文件,获取文件路径。
  2. 上传 :使用 uni.uploadFile 上传该本地文件。

由于 App/小程序H5 的底层机制不同,处理方式有所区别。以下是完整的解决方案。


方案概览

场景一:App 端 (Android/iOS) 与 小程序

App 和小程序支持文件系统管理器 (FileSystemManager),这是最推荐、最稳定的方式。

1. 定义转换工具函数

我们需要一个函数,将 Base64 去掉头部(如果有),写入本地临时目录,并返回路径。

javascript 复制代码
/**
 * 将 Base64 字符串转为本地临时路径 (App/小程序专用)
 * @param {String} base64data - 带头部的base64字符串 (如 data:image/png;base64,...)
 * @returns {Promise<String>} - 返回本地临时文件路径
 */
function base64ToPath(base64data) {
  return new Promise((resolve, reject) => {
    // 1. 获取全局唯一的文件管理器
    const fs = uni.getFileSystemManager();
    
    // 2. 处理 Base64 头部,提取纯数据
    // 正则匹配 data:image/png;base64, 这种格式
    const base64Body = base64data.replace(/^data:image\/\w+;base64,/, "");
    
    // 3. 创建临时文件路径 (使用时间戳确保文件名唯一)
    // wx.env.USER_DATA_PATH 在小程序和App中均可用
    const filePath = `${uni.env.USER_DATA_PATH}/temp_image_${Date.now()}.png`;

    // 4. 写入文件
    fs.writeFile({
      filePath: filePath,
      data: base64Body,
      encoding: 'base64',
      success: () => {
        resolve(filePath);
      },
      fail: (err) => {
        reject(err);
      }
    });
  });
}
2. 调用并上传
javascript 复制代码
async function handleUpload(base64Str) {
  try {
    uni.showLoading({ title: '处理中...' });

    // 第一步:转为本地路径
    const tempFilePath = await base64ToPath(base64Str);
    console.log('本地临时路径:', tempFilePath);

    // 第二步:上传文件
    uni.uploadFile({
      url: 'https://your-api.com/upload', // 你的后端接口
      filePath: tempFilePath,
      name: 'file', // 后端接收的字段名
      formData: {
        'user_id': '123' // 其他需要携带的参数
      },
      success: (uploadFileRes) => {
        console.log('上传成功', uploadFileRes.data);
      },
      fail: (err) => {
        console.error('上传失败', err);
      },
      complete: () => {
        uni.hideLoading();
      }
    });

  } catch (error) {
    uni.hideLoading();
    console.error('转换失败', error);
    uni.showToast({ title: '图片处理失败', icon: 'none' });
  }
}

场景二:H5 (Web端)

H5 无法像 App 那样直接访问本地文件系统,而是使用 Blob 对象。虽然 uni.uploadFile 在 H5 端也支持 file 对象,但更常见的做法是直接处理 Blob。

1. 定义转换工具函数 (Base64 转 Blob)
javascript 复制代码
/**
 * 将 Base64 转为 Blob 对象 (H5专用)
 */
function base64ToBlob(base64data) {
  const arr = base64data.split(',');
  const mime = arr[0].match(/:(.*?);/)[1];
  const bstr = atob(arr[1]);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  
  return new Blob([u8arr], { type: mime });
}
2. H5 端上传逻辑

在 H5 中,uni.uploadFile 内部会自动处理 Blob,或者你可以直接使用 uni.request 发送 FormData

javascript 复制代码
function handleH5Upload(base64Str) {
  // 1. 转为 Blob
  const blob = base64ToBlob(base64Str);
  
  // 注意:uni.uploadFile 在 H5 端可以直接传 Blob 给 filePath 吗?
  // 官方文档建议 H5 端将 blob 放入 file 对象中,或使用 FormData
  // 下面是兼容性较好的 FormData 方式,使用 uni.request
  
  const formData = new FormData();
  formData.append('file', blob, 'image.png'); // 第三个参数是文件名
  formData.append('user_id', '123');

  uni.request({
    url: 'https://your-api.com/upload',
    method: 'POST',
    data: formData,
    // H5 端 fetch/xhr 会自动设置 Content-Type 为 multipart/form-data,不要手动设置 header
    success: (res) => {
      console.log('H5上传成功', res);
    }
  });
}

综合兼容写法 (推荐)

为了让代码一套逻辑跑通所有端,可以使用条件编译或运行时检查。

javascript 复制代码
async function uploadBase64Image(base64Str) {
  // #ifdef H5
  // H5 逻辑
  const blob = base64ToBlob(base64Str);
  // 这里演示直接用 uni.uploadFile (UniApp H5端做了兼容,filePath 可以传 Blob 的 URL)
  // 但更推荐上面 FormData 的方式。如果必须用 uni.uploadFile:
  // const fileUrl = URL.createObjectURL(blob); 
  // 然后传 fileUrl 给 filePath,用完记得 URL.revokeObjectURL
  // #endif

  // #ifndef H5
  // App 和 小程序 逻辑
  try {
    const filePath = await base64ToPath(base64Str);
    uni.uploadFile({
      url: 'https://api.example.com/upload',
      filePath: filePath,
      name: 'file',
      success: (res) => {
        console.log('上传完成', res);
      }
    });
  } catch (e) {
    console.error(e);
  }
  // #endif
}
相关推荐
2501_915918413 小时前
Wireshark、Fiddler、Charles抓包工具详细使用指南
android·ios·小程序·https·uni-app·iphone·webview
阿宇爱吃鱼3 小时前
uniapp input输入框,限制金额输入格式
前端·javascript·uni-app
一只程序熊3 小时前
uniapp x 新手入门指南
uni-app
攻城狮7号12 小时前
不懂代码也能造?TRAE+GLM-4.6 手把手教你搭心理咨询智能客服小程序
python·小程序·uni-app·vue·trae·glm我的编程搭子·glm-4.6
QQ5885019814 小时前
Python_uniapp-心理健康测评服务微信小程序的设计与实现
python·微信小程序·uni-app
三天两行代码14 小时前
uniapp 微信小程序实现ai问答功能流式输出makdown解析实现打字机效果(附源码)
微信小程序·小程序·uni-app
三天不学习14 小时前
从开发到上架:手把手教你将uni-app微信小程序打包发布(全网最全指南)
微信小程序·uni-app·notepad++
木子啊16 小时前
UniApp原生Office预览组件上线
uni-app·在线预览·预览文件·office预览文件
2501_9151063217 小时前
如何在iPad上高效管理本地文件的完整指南
android·ios·小程序·uni-app·iphone·webview·ipad