uniapp不同平台获取文件内容以及base64编码特征

前言

文件图片上传,客户端预览是很正常的需求,获取文件的md5特征码也是很正常的,那么,在uniapp中三种环境,h5, 小程序以及 app环境下,如何实现的?
参考:
如何在uniapp中读取文件ArrayBuffer和sha256哈希值,支持H5、APP、小程序

uniapp 没有提供跨平台的 API 来获取文件的 sha256 哈希值和读取文件的 ArrayBuffer,因此需要开发者自己手动兼容各个平台。在小程序端使用FileSystemManager、app 端是plus.io、H5 端是FileReader,这些 API 都是平台特有的,而且实际调用存在各种问题,也缺乏相关教程

uniapp-微信小程序-图片转base64

ps:只适合小文件上传,大文件的话不要用这个。计算md5的时候采用了sparkMD5,请自行安装。

具体实现

必须要知道的是文件的临时路径,就是:
http://xxxxx 形式的

例如:

// 读取图像文件
uni.chooseImage({count: 9,sizeType: ['original', 'compressed'],sourceType: ['album', 'camera'],success: (res) => {const tempFilePaths = res.tempFilePaths// tempFilePaths 是一个数组,可以通过索引获取图片路径,比如tempFilePaths[0],我们需要的就是这个路径},
})

或者

	uni.chooseMedia({count:1,// 限制选取图像数量mediaType:["image"],// 设置选取资源为图片类型sourceType:["album","camera"],// 设置图像来源:相册或相机camera:"back",// 设置相机为后置摄像头success:(res)=>{// 获取微信拿到的图片的临时地址并保存到本地this.photoPath=res.tempFiles[0].tempFilePath;}})
},

小程序获取 ArrayBuffer以及读取base64:

arrayBuffer:
// 小程序,filePath 是一个本地文件路径
const fs = uni.getFileSystemManager()
return fs.readFileSync(filePath)
base64:
// (由于uniapp开发所以uni打头)
uni.getFileSystemManager().readFile({// 【重点来啦】人家自提供的转码APIfilePath:image.path,// 所需转码图像路径encoding:"base64",// 转码类型success:(res)=>{// 生成base64let imageBase64='data:image/'+image.type+';base64,'+res.data;console.log('转base64后:',imageBase64);}
})

H5获取 ArrayBuffer以及读取base64:

const blobURLToBlob = (url) => {return new Promise((resolve, reject) => {var http = new XMLHttpRequest()http.open('GET', url, true)http.responseType = 'blob'http.onload = function (e) {if (this.status == 200 || this.status === 0) {resolve(this.response)} else {reject(this.status)}}http.send()})
}//  通过blob:url读取实际的ArrayBuffer数据
const H5ReadBlobUrlArrayBuffer = (blobUrl) => {return new Promise(async (resolve, reject) => {try {const reader = new FileReader()// blob数据转file对象数据const fileBlob: any = await blobURLToBlob(blobUrl)const file = new window.File([fileBlob], 'file.name', { type: 'file.type' })// 读取file对象ArrayBufferreader.readAsArrayBuffer(file)reader.onload = function (e) {resolve(e?.target?.result)}} catch (e) {reject(e)}})
}
//  通过blob:url读取实际的base64:
const H5ReadBlobUrlBase64 = (blobUrl) => {return new Promise(async (resolve, reject) => {try {const reader = new FileReader()// blob数据转file对象数据const fileBlob: any = await blobURLToBlob(blobUrl)const file = new window.File([fileBlob], 'file.name', { type: 'file.type' })// 读取file对象ArrayBufferreader.readAsDataURL(file)reader.onload = function (e) {resolve(e?.target?.result)}} catch (e) {reject(e)}})
}注意:实际上 h5都是使用fileReader的api来读取的,arrayBuffer是:readAsArrayBuffer,而base64是readAsDataURL,不但图片,文件也能这样读取base64的。

APP获取 ArrayBuffer以及读取base64:

const H5PlusReadFileArrayBuffer = (filePath) => {return new Promise((resolve, reject) => {try {plus.io.resolveLocalFileSystemURL(filePath,function (entry) {entry?.file(function (file) {const fileReader = new plus.io.FileReader()fileReader.readAsDataURL(file, 'utf-8')fileReader.onloadend = function (evt) {const result = {base64: evt.target.result.split(',')[1],size: file.size,}resolve(uni.base64ToArrayBuffer(result.base64))}})},function (error) {reject(error)},)} catch (error) {reject(error)}})
}

app方面是直接先读取base64,再读取arrayBuffer,所以一气呵成。

综合:

import  SparkMD5 from 'spark-md5';
export interface FileReaderInfo {fileHeader64:string;//--base64形式的文件前一段内容,用于传递magicNumber进行判断。base64:string;arrayBuffer:any;tempPath:string;//形式如下:blob:http://localhost:3000/5fd140d3-1372-4394-8b08-0cba8c508099mime:string;errMsg?:string;md5:string,//--获取文件md5.
}// #ifdef H5
// 通过blob:url读取实际的blob数据
function  h5_blobURLToBlob  (url:string) :Promise<any> {return new Promise((resolve, reject) => {var http = new XMLHttpRequest();http.open('GET', url, true)http.responseType = 'blob';http.onload = function (e) {if (this.status == 200 || this.status === 0) {resolve(this.response)} else {reject(this.status)}};http.send()})
}//  通过blob:url读取实际的ArrayBuffer数据function H5ReadBlobUrl(blobUrl:string,mimeType:string): Promise<FileReaderInfo> {let intervalInst:any=null;const fileinfo:FileReaderInfo={fileHeader64:"",tempPath:blobUrl,arrayBuffer:null,base64:"",mime:mimeType,md5:"",};return new Promise<FileReaderInfo>(async (resolve, reject) => {try {const reader = new FileReader();const reader64 = new FileReader();// blob数据转file对象数据const fileBlob: any = await h5_blobURLToBlob(blobUrl);const file = new window.File([fileBlob], 'file.name', { type: mimeType });// 读取file对象ArrayBufferreader.readAsArrayBuffer(file);reader64.readAsDataURL(file);reader.onload = function (e) {const data:any=e?.target?.result;// let spark = new SparkMD5(); // 创建md5对象(基于SparkMD5)let spark = new SparkMD5.ArrayBuffer();spark.append(data);fileinfo.md5=spark.end();fileinfo.arrayBuffer=data;};reader64.onload = function (e) {fileinfo.base64=(e?.target?.result+"");let subPosIdx = (fileinfo.base64 + "").indexOf(",");let headerContent = fileinfo.base64.substr(subPosIdx + 1, 160);fileinfo.fileHeader64=headerContent;};intervalInst=setInterval(()=>{if(fileinfo.base64&&fileinfo.arrayBuffer){clearInterval(intervalInst);resolve(fileinfo);}},100);} catch (e) {if(intervalInst){clearInterval(intervalInst);}reject(e)}})
}
// #endif// #ifdef APP-PLUS
// 通过plus.io读取文件的ArrayBuffer数据
function H5PlusReadFile  (filePath:string,mimeType:string) :Promise<FileReaderInfo> {const fileinfo:FileReaderInfo={fileHeader64:"",tempPath:filePath,arrayBuffer:null,base64:"",mime:mimeType,md5:"",};return new Promise<FileReaderInfo>((resolve, reject) => {try {plus.io.resolveLocalFileSystemURL(filePath,function (entry:any) {entry?.file(function (file:any) {const fileReader = new plus.io.FileReader();fileReader.readAsDataURL(file, 'utf-8');fileReader.onloadend = function (evt:any) {fileinfo.base64=(evt?.target?.result+"");let subPosIdx = (fileinfo.base64 + "").indexOf(",");let headerContent = fileinfo.base64.substr(subPosIdx + 1, 160);fileinfo.fileHeader64=headerContent;const result = {base64: evt.target.result.split(',')[1],size: file.size,};const data:any=uni.base64ToArrayBuffer(result.base64);// let spark = new SparkMD5(); // 创建md5对象(基于SparkMD5)let spark = new SparkMD5.ArrayBuffer();spark.append(data);fileinfo.md5=spark.end();fileinfo.arrayBuffer=data;resolve(fileinfo);}})},function (error) {reject(error)},)} catch (error) {reject(error)}})
}
// #endiffunction MpReadFile(filePath:string,mimeType:string) :Promise<FileReaderInfo>{const fileinfo:FileReaderInfo={fileHeader64:"",tempPath:filePath,arrayBuffer:null,base64:"",mime:mimeType,md5:"",};return new Promise<FileReaderInfo>((resolve, reject) => {if (uni.canIUse('getFileSystemManager') && uni.getFileSystemManager) {}else{fileinfo.errMsg="无效环境,不可调用api!";reject(fileinfo);return ;}const fs = uni.getFileSystemManager();const data:any = fs.readFileSync(filePath);// let spark = new SparkMD5(); // 创建md5对象(基于SparkMD5)let spark = new SparkMD5.ArrayBuffer();spark.append(data);fileinfo.md5=spark.end();fileinfo.arrayBuffer=data;fs.readFile({// 【重点来啦】人家自提供的转码APIfilePath: filePath,// 所需转码图像路径encoding: "base64",// 转码类型success: (res) => {// 生成base64// let imageBase64 = 'data:image/' + image.type + ';base64,' + res.data;let imageBase64 = res.data;console.log('转base64后:', imageBase64);fileinfo.base64=(imageBase64+"");let subPosIdx = (fileinfo.base64 + "").indexOf(",");let headerContent = fileinfo.base64.substr(subPosIdx + 1, 160);fileinfo.fileHeader64=headerContent;resolve(fileinfo);}});});
}// 对外暴露的方法,通过这个方法获取文件的ArrayBuffer,内部会根据平台调用不同的方法
export const readFileDataExt = async (filePath:string,mimeType:string) : Promise<FileReaderInfo> => {if (uni.canIUse('getFileSystemManager') && uni.getFileSystemManager) {return MpReadFile(filePath,mimeType);}// #ifdef APP-PLUSelse if (plus.io) {return H5PlusReadFile(filePath,mimeType);}// #endif// #ifdef H5else if (XMLHttpRequest) {return H5ReadBlobUrl(filePath,mimeType);}// #endifelse {throw new Error('不支持的平台');}
};

实际运行效果

H5平台

选择图片进行上传:图片的数据如下:

在这里插入图片描述
在这里插入图片描述

ps:文件的md5,不同的文件是一定不同的,如果你获得的md5是一样的—那么就好好检查一下,spark获取md5的时候是不是都是同一个东西了。

其他场景有条件再测试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/479065.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Guitar Pro 8.1 Mac 2024最新下载、安装、激活、换机图文教程

Guitar Pro 8是吉他手的终极工具箱,也是阅读和编辑乐谱的领先软件。26 年来,Guitar Pro 一直在帮助世界各地的音乐家学习弹吉他、创作歌曲以及转录和编辑歌集。 Guitar Pro是一款专业的吉他制谱软件&#xff0c;现在已更新至Guitar Pro8&#xff0c;新增了支持添加音频轨道、支…

C++拷贝构造函数与赋值运算符重载

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、拷贝构造函数 1.概念 在现实生活中&#xff0c;可能存在一个与你一样的自己&#xff0c;我们称其为双胞胎。 那在创…

ClickHouse 基础(一)

官网 ClickHouse release 24.1, 2024-01-30 以毫秒为单位查询数十亿行 ClickHouse是用于实时应用和分析的最快、资源效率最高的开源数据库。 安装ClickHouse 使用ClickHouse&#xff0c;你有三个选择: ClickHouse云:官方ClickHouse作为一项服务&#xff0c;-由ClickHouse的创…

openGauss 5.0.0全密态数据库应用小试

前言 openGauss HCIA教材中&#xff0c;安全是一个重要的章节&#xff0c;在实际项目中&#xff0c;随着网络安全和信息安全形势的变化&#xff0c;企业也越来越重视数据库安全。去年在HALP内部进行openGauss培训时&#xff0c;安全特性就被学员们提出来要重点讲解&#xff0c…

免费改文案的软件有哪些,为大家分享四款!

随着数字化时代的到来&#xff0c;文案写作已经成为许多企业和个人必备的技能。要在众多文案中脱颖而出并不容易。所幸的是&#xff0c;如今有许多免费改文案的软件可以帮助我们快速而高效地完成这项工作。本文将介绍一些常见的免费改文案的软件&#xff0c;帮助大家选择适合自…

【C++】vector模拟实现+迭代器失效

vector模拟实现 成员变量定义默认成员函数构造函数 迭代器范围for、对象类型匹配原则 容量操作sizeemptycapacityreserve成员变量未更新memcpy值拷贝 resize内置类型的构造函数 数据访问frontbackoperator[ ] 数据修改操作push_backpop_backswapclearinsertpos位置未更新无返回…

2、windows环境下vscode开发c/c++环境配置(一)

前言&#xff1a;VSCode是微软出的一款轻量级编辑器&#xff0c;它本身只是一款文本编辑器而已&#xff0c;并不是一个集成开发环境(IDE)&#xff0c;几乎所有功能都是以插件扩展的形式所存在的。因此&#xff0c;我们想用它编程&#xff0c;不只是把vscode下载下来就行&#x…

卡诺模型驱动人工智能革新:重塑未来智能生态!

在数字化浪潮席卷全球的今天&#xff0c;人工智能&#xff08;AI&#xff09;已成为推动社会进步的重要力量。而卡诺模型&#xff0c;作为一种经典的产品设计和优化工具&#xff0c;正以其独特的视角和强大的分析能力&#xff0c;为人工智能领域注入新的活力&#xff0c;赋能AI…

GPIO控制和命名规则

Linux提供了GPIO子系统驱动框架&#xff0c;使用该驱动框架即可灵活地控制板子上的GPIO。 GPIO命名 泰山派开发板板载了一个40PIN 2.54间距的贴片排针&#xff0c;排针的引脚定义兼容经典40PIN接口。 在后续对GPIO进行操作前&#xff0c;我们需要先了解k3566的GPIO命名规则&a…

城市级智慧排水管网监测,综合预警管理系统

通过城市智慧排水管网监测系统的建设&#xff0c;实现对管网上窨井井盖状态、管网液位、管网流量、管网有害气体、管网水质等数据采集&#xff0c;实时掌握排水管网运行状况&#xff0c;为排水管网的运行调度、养护管理、快速响应提供有效的数据支持&#xff0c;以便于管理者掌…

2024年护眼大路灯横评推荐:书客、霍尼韦尔、松下落地灯哪款才是性能之王?

大路灯逐渐成为学生党、上班族的必备家电&#xff0c;但很多朋友对大路灯了解较少&#xff0c;对大路灯怎么选还有很多疑问&#xff0c;市场大路灯品牌、型号琳琅满目&#xff0c;不知道大路灯哪个品牌好&#xff1f; 本文通过对市面上热门品牌型号测评对比&#xff0c;系统性介…

代码随想录算法训练营DAY20 | 二叉树 (8)

一、LeetCode 701 二叉搜索树中的插入操作 题目链接&#xff1a; 701.二叉搜索树中的插入操作https://leetcode.cn/problems/insert-into-a-binary-search-tree/description/ 思路&#xff1a;见缝插针罢辽。 class Solution {public TreeNode insertIntoBST(TreeNode root, i…