uniapp 上传二进制流图片
文章目录
- 场景
- 🟢一、步骤
- 1.1、选择图片
- 1.2、 读取图片为二进制数据
- 1.3、上传二进制数据到服务器
- 🟢二、项目案例
- 2.1、替换头像案例
- 2.1、uView u-upload 上传封面
- 🟢 三、关键注意事项
- 3.1 二进制流与 FormData 区别
- 3.2 性能优化
- 3.3 跨平台适配
- ✒️总结
场景
在日常开发中,常需实现用户头像更换、图片附件上传等功能。通过将图片转换为二进制流上传,可灵活适配不同后端接口需求,本文将详细介绍具体实现步骤及项目案例。
🟢一、步骤
在 UniApp 中上传二进制流图片,一般需要经过选择图片、读取为二进制数据、上传二进制数据到服务器这几个主要步骤
1.1、选择图片
使用 uni.chooseMedia 或 uni.chooseImage 方法让用户从相册或相机选择图片。
uni.chooseMedia(推荐,UniApp 3.1.0+ 支持)或 uni.chooseImage 调用系统媒体选择器。
uni.chooseMedia({count: 1, // 选择图片的数量mediaType: ['image'], // 只选择图片success: (res) => {const tempFilePath = res.tempFiles[0].tempFilePath;// 后续可将 tempFilePath 用于读取二进制数据},fail: (err) => {console.error('选择图片失败:', err);}
});
1.2、 读取图片为二进制数据
使用 uni.getFileSystemManager().readFile 方法将选择的图片文件读取为ArrayBuffer 格式二进制数据
uni.getFileSystemManager().readFile({filePath: tempFilePath,success: (fileRes) => {const binaryData = fileRes.data;// 后续可将 binaryData 用于上传},fail: (err) => {console.error('读取文件失败:', err);}
});
1.3、上传二进制数据到服务器
通过 uni.request 发送二进制流,需注意请求头设置为 application/octet-stream。
uni.request({url: 'https://xxx/upload', // 服务器上传接口地址method: 'POST',data: binaryData,headers: {'Content-Type': 'application/octet-stream'},success: (res) => {if (res.statusCode === 200) {console.log('上传成功:', res.data);} else {console.error('上传失败,状态码:', res.statusCode);}},fail: (err) => {console.error('上传失败:', err);}
});
🟢二、项目案例
2.1、替换头像案例
uni.chooseMedia+uni.getFileSystemManager().readFile方案实现
页面结构
<view class="img-box" @click="onAvatatChange"><image mode="aspectFill" class="img" :src="addformData.avatar"></image><view class="text">点击更换头像</view></view>
逻辑实现
// 修改头像onAvatatChange() {// 调用拍照/选择图片uni.chooseMedia({count: 1,mediaType: ['image'],success: (res) => {console.log(res.tempFiles[0].tempFilePath)const tempFilePath = res.tempFiles[0].tempFilePath;// 读取图片文件为二进制数据uni.getFileSystemManager().readFile({filePath: tempFilePath,success: (fileRes) => {const binaryData = fileRes.data;// 上传二进制数据到服务器this.uploadBinaryData(binaryData, tempFilePath);},fail: (err) => {console.error('读取文件失败:', err);uni.showToast({title: '读取文件失败',icon: 'none'});}});}})},uploadBinaryData(binaryData, tempFilePath) {uni.uploadFile({url: "https://xxxx/file/upload",method: 'POST',formData: binaryData,filePath: tempFilePath,name: "file",header: {'Authorization': uni.getStorageSync('token'),'Content-Type': 'multipart/form-data'},success: (res) => {let resut = JSON.parse(res.data)if (resut.code == 200) {this.addformData.avatar = resut.data.url}},})},
2.1、uView u-upload 上传封面
页面结构
<u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple:maxCount="1"></u-upload>
// 删除图片deletePic(event) {console.log('删除', event)this.api.FileDelete({filePath: event.file.baseUrl}).then(res => {console.log('删除附件', res)uni.showToast({title: '删除成功',icon: 'success',duration: 1500});this[`fileList${event.name}`].splice(event.index, 1);})},// 新增图片async afterRead(event) {// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式let lists = [].concat(event.file);let fileListLen = this[`fileList${event.name}`].length;lists.map((item) => {this[`fileList${event.name}`].push({...item,status: "uploading",message: "上传中",});});for (let i = 0; i < lists.length; i++) {const result = await this.uploadFilePromise(lists[i]);let item = this[`fileList${event.name}`][fileListLen];this[`fileList${event.name}`].splice(fileListLen,1,Object.assign(item, {status: "success",message: "",url: result.url,name: result.name,baseUrl: result.baseUrl,}));fileListLen++;}},//上传图片uploadFilePromise(file) {console.log('file', file)return new Promise((resolve, reject) => {uni.getFileSystemManager().readFile({filePath: file.url,encoding: 'binary',success: (readRes) => {console.log('readRes', readRes)console.log('文件内容长度:', readRes.data.length);uni.uploadFile({// url: "http://xxx/file/upload", // 仅为示例,非真实的接口地址url: "https://xxxx/file/upload", // 仅为示例,非真实的接口地址filePath: file.url,name: "file",// header: {// 'Authorization': uni.getStorageSync('token'),// 'Content-Type': 'application/octet-stream'// },header: {// 添加请求头'Authorization': uni.getStorageSync('token'),// 可以添加其他请求头'Content-Type': 'multipart/form-data'},formData: readRes,// formData: {// user: "test",// },success: async (res) => {console.log('res文件上传', res)setTimeout(() => {resolve(JSON.parse(res.data).data);uni.showToast({title: '上传成功',icon: 'success',duration: 1500});}, 1000);},fail: (err) => {reject(err);}});},fail: (err) => {reject(err);}});});},
🟢 三、关键注意事项
3.1 二进制流与 FormData 区别
方式 | 适用场景 | 请求头设置 | 后端 |
---|---|---|---|
二进制流 | 纯文件字节流传输 | Content-Type: application/octet-stream | 直接读取请求体字节数据 |
FormData 封装 | 需附带其他字段(如业务参数) | Content-Type: multipart/form-data | 通过 file 字段解析文件 |
3.2 性能优化
- 压缩图片:上传前通过
uni.compressImage
压缩图片,减少传输数据量。 - 并行上传:使用
Promise.all
并行处理多图上传(需注意服务器接口是否支持)。 - 进度监听:通过
uni.uploadFile
的onProgressUpdate
回调显示上传进度条。
3.3 跨平台适配
- 小程序平台:
uni.chooseMedia
自动适配微信/支付宝/字节等小程序的图片选择接口。 - H5 平台:需确保服务器支持跨域请求(设置
Access-Control-Allow-Origin
)。 - App 平台:需在 manifest 中配置文件读写权限(
FS_WRITE_ACCESS
)。
✒️总结
UniApp 中上传二进制流图片的核心在于:
- 通过
uni.chooseMedia
或uni.chooseImage
获取图片临时路径; - 使用文件系统 API 读取为二进制数据;
- 根据后端要求选择
uni.request
(二进制流)或uni.uploadFile
(FormData 表单)上传。
实际开发中,建议优先使用 uni.chooseMedia
统一跨平台体验,并根据接口规范灵活设置请求头。对于复杂场景(如多图上传、进度显示),可结合组件库(如 uView)或自定义指令优化交互体验。
如果本文对你有帮助,欢迎点赞支持!如需进一步探讨前端或 UniApp 开发,可访问我的个人主页「前端初见」,期待与你共同成长!
如果这篇【文章】有帮助到你💖,希望可以给我点个赞👍,创作不易,如果有对前端端或者对python感兴趣的朋友,请多多关注💖💖💖,咱们一起探讨和努力!!!
👨🔧 个人主页 : 前端初见
相关文章:

uniapp 上传二进制流图片
文章目录 场景🟢一、步骤1.1、选择图片1.2、 读取图片为二进制数据1.3、上传二进制数据到服务器 🟢二、项目案例2.1、替换头像案例2.1、uView u-upload 上传封面 🟢 三、关键注意事项3.1 二进制流与 FormData 区别3.2 性能优化3.3 跨平台适配…...

赛灵思 XCKU115-2FLVB2104I Xilinx Kintex UltraScale FPGA
XCKU115-2FLVB2104I 是 AMD Xilinx Kintex UltraScale FPGA,基于 20 nm 先进工艺,提供高达 1 451 100 个逻辑单元(Logic Cells),77 721 600 bit 的片上 RAM 资源,以及 5 520 个 DSP 切片(DSP48E…...

Unreal Niagara制作SubUV贴图翻页动画
SubUV翻页动画是游戏中的常见功能,通过对每一小块UV进行移动可以模拟动画效果,接下来对下图进行SubUV动画的制作。 (金币测试图下载地址:https://download.csdn.net/download/grayrail/90684422) 最终效果如下: 1.…...

「零配置陷阱」:现代全栈工具链的复杂度管控实践
一、工具链膨胀的「死亡螺旋」 2024年典型全栈项目的初始化噩梦: $ npm create vitelatest ✔ Project name: … demo ✔ Select a framework: › React ✔ Select a variant: › TypeScript SWC ✔ Install shadcn/ui? … Yes ✔ Add Storybook? … Yes ✔ Co…...

金仓数据库KingbaseES技术实践类深度剖析与实战指南
一、语法兼容及迁移实战 (一)语法兼容的多元魅力 在当今多元化的数据库应用环境中,金仓数据库管理系统KingbaseES凭借其卓越的语法兼容能力脱颖而出。它采用的融合数据库架构,通过多语法体系一体化架构,实现了对Orac…...

基于ssm的个人博客管理系统(源码+数据库+万字文档)
57基于ssm的个人博客管理系统:前端jsp、jquery、easyui,后端 spring、mybatis、maven,集成个人博客浏览、详情查看、博客发布、富文本编辑、评论等功能于一体的系统。 ## 功能介绍 ### 用户 - 首页:博客列表、博客详情、关键词…...
c#加密证件号的中间部分,改为*号
前言 使用场景:在我项目中,我需要给前端提供接口,所以我要吧证件号进行加密。例如:411421199510225612,这是一个身份证号,18为的,那么我加密完成之后就会是 411421********5612,类似…...

综述 | GUI Agent:让AI学会「玩手机」的新革命
想象一下,你的手机里住着一个隐形助理:你说“把亮度调到50%”,它自动操作;你说“下载最新游戏”,它一键完成。这就是GUI智能体——一种能“看懂”屏幕并操作的AI。 论文:A Survey on (M)LLM-Based GUI Agen…...

Canvas入门教程!!【Canvas篇二】
没有一朵花,从一开始就是花。 目录 translate() 方法:rotate() 方法:scale() 方法: translate() 方法: Canvas 2D API 的 CanvasRenderingContext2D.translate() 方法用于对当前网格添加平移变换。 translate() 方法通…...

【中级软件设计师】函数调用 —— 传值调用和传地址调用 (附软考真题)
【中级软件设计师】函数调用 —— 传值调用和传地址调用 (附软考真题) 目录 【中级软件设计师】函数调用 —— 传值调用和传地址调用 (附软考真题)一、历年真题二、考点:函数调用 —— 传值调用和传地址调用🔺1、传值调用🔺2、传引用(地址)调…...

第七届能源系统与电气电力国际学术会议(ICESEP 2025)
重要信息 时间:2025年6月20-22日 地点:中国-武汉 官网:www.icesep.net 主题 能源系统 节能技术、能源存储技术、可再生能源、热能与动力工程 、能源工程、可再生能源技术和系统、风力发…...

大数据分析04 数据查询分析
构建数据源 引入pandas包 数据map中ID为列,值为行,每一列中值个数要一致 import pandas as pd data {ID: [000001, 000002, 000003, 000004, 000005, 000006, 000007],name:[黎明, 赵怡春, 张富平, 白丽, 牛玉德, 姚华, 李南], gender:[True, False, …...

ADVB协议同步
关于视频传输,有多种控制时序。协议标准允许设计者选择有限的几个速率的接口来满足 系统设计目标。例如,一些系统使用总线时序发送信息通过line-by-line;在这个案例中, 容器的sof作为vsync同步的点。horizontal line blanding将插入idles,ADV…...

【kafka初学】启动执行命令
接上篇,启动:开两个cdm窗口 注意放的文件不要太深或者中文,会报命令行太长的错误 启动zookeeper bin\windows\zookeeper-server-start.bat config\zookeeper.properties2. 启动kafka-serve bin\windows\kafka-server-start.bat config\serv…...

论文阅读笔记——π0.5: a Vision-Language-Action Model with Open-World Generalization
π0.5 论文 通过异构数据协同训练与分层推理,用中等规模的目标数据(400小时)实现了大规模泛化能力,为现实世界机器人学习提供了新范式。 高层推理(high-level) 根据当前观测和任务指令预测子任务(如“打开抽屉”&…...

电子削铅笔刀顺序图详解:从UML设计到PlantUML实现
题目:为电子削铅笔刀建立一个顺序图和一个通信图。图中的对象包括操作者、铅笔、插入点(也就是铅笔插入铅笔刀的位置)、马达和其他元素。包括哪些交互消息?有那些激活?如何在图中表示出自身调用。 一、顺序图概述 顺序图(Sequence Diagram)…...

FWFT_FIFO和Standard_FIFO对比仿真
在FPGA中使用FIFO时,如果使用FPGA厂商提供的FIFO IP,一般都会有First Word Fall Through FIFO和Standard FIFO类型选项,那么这两种FIFO有什么差异么。两种FIFO的端口是一样的,看不出区别,只有通过仿真,才能…...

什么是可重入锁ReentrantLock?
大家好,我是锋哥。今天分享关于【什么是可重入锁ReentrantLock?】面试题。希望对大家有帮助; 什么是可重入锁ReentrantLock? ReentrantLock 是 Java 中的一个锁实现,它是 java.util.concurrent.locks 包中的一部分,主要用于提供…...

利用JMeter代理服务器方式实现高效压测
前言 在当今快节奏的互联网时代,确保Web应用和服务能够在高负载下稳定运行变得至关重要。无论是电子商务平台、社交媒体网络还是在线教育服务,用户对网站响应速度和稳定性的期望从未如此之高。因此,性能测试不再是一个可选项,而是…...

WSL 安装过程整理
WSL 安装过程整理 一、WSL 安装教程二、安装后小技巧1、安装位置2、常用命令 三、在 WSL2 中安装 perf: 一、WSL 安装教程 史上最全的WSL安装教程 WSL2 最新最全帮助小白一步步详细安装教程 在WSL2 root 和普通用户的切换 轻松搬迁!教你如何将WSL从C盘迁…...
【go】简单理解梳理go的内存分配原理
Go 内存分配机制原理 Go 的内存分配机制设计非常精细,结合了多级缓存、对象池和垃圾回收等机制,以实现高并发下的高性能分配。 1. 整体内存结构 Go 程序启动时,运行时会向操作系统申请一大块连续内存区域(heap arena࿰…...
GStreamer 简明教程(十一):插件开发,以一个音频生成(Audio Source)插件为例
系列文章目录 GStreamer 简明教程(一):环境搭建,运行 Basic Tutorial 1 Hello world! GStreamer 简明教程(二):基本概念介绍,Element 和 Pipeline GStreamer 简明教程(三…...
【阿里云大模型高级工程师ACP学习笔记】2.1 用大模型构建新人答疑机器人
学习目标 在备考阿里云大模型高级工程师ACP认证时,学习《2.1用大模型构建新人答疑机器人》这部分内容,主要是为了掌握利用大模型技术构建高效答疑机器人的方法,提升在大模型应用开发领域的专业能力。具体目标如下: 掌握大模型API调用:学会通过API调用通义千问大模型,熟悉…...
嵌入式鸿蒙系统环境搭建与配置要求实现01
各位开发者大家好,今天主要给大家分享一下,鸿蒙系统的环境配置实现。 第一:鸿蒙配置基本要求 对电脑的要求,虚拟机配置建议 200GB 硬盘大小,10GB 内存,4*2CPU。 安装必要的依赖文件方法: sudo apt-get update && sudo apt-get install binutils git git-lfs g…...

form表单提交前设置请求头request header及文件下载
需求:想要在form表单submit之前,设置一下请求头。 除了用Ajax发起请求之外,还可以使用FormData来实现,咱不懂就问。 1 问:FormData什么时间出现的?与ajax什么联系? 2 问:FormData使…...

【c++11】c++11新特性(下)(可变参数模板、default和delete、容器新设定、包装器)
🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:C 目录 前言 五、可变参数模板 1. 概念及简单定义 2. 包扩展 六、 default和delete 七、容器新设定 1. 新容器 2. 新接口 emplace系列接口 八、函数包…...

PyTorch 实现食物图像分类实战:从数据处理到模型训练
一、简介 在计算机视觉领域,图像分类是一项基础且重要的任务,广泛应用于智能安防、医疗诊断、电商推荐等场景。本文将以食物图像分类为例,基于 PyTorch 框架,详细介绍从数据准备、模型构建到训练测试的全流程,帮助读者…...

Qt —— 在Linux下试用QWebEngingView出现的Js错误问题解决(附上四种解决办法)
错误提示:js: A parser-blocking, cross site (i.e. different eTLD+1) script, https:xxxx, is invoked via document.write. The network request for this script MAY be blocked by the browser in this or a future page load due to poor network connectivity. If bloc…...

命名空间(C++)
命名空间主要用于大型项目中。 局部命名在该局部会覆盖全局命名。C语言中唯一一种在局部调用全局相同命名的全局变量的方式:指针在C中可以用作用域运算符来访问全局变量,作用域运算符的前面可以是作用域也可以是类。 命名空间实际上是对全局作用域的再次…...
使用Python脚本在Mac上彻底清除Chrome浏览历史:开发实战与隐私保护指南
题目: 《基于PyCharm与Mac系统的Chrome历史记录清理工具开发实战》 引言 在Mac系统下,Chrome浏览器的历史记录文件通常以SQLite数据库形式存储于用户目录中,仅通过浏览器内置功能清理可能残留索引文件。本文通过一个Python脚本(c…...