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

news2025/1/10 18:05:11

前言

文件图片上传,客户端预览是很正常的需求,获取文件的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({// 【重点来啦】人家自提供的转码API
	filePath:image.path,// 所需转码图像路径
	encoding:"base64",// 转码类型
	success:(res)=>{
	    // 生成base64
	    let 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对象ArrayBuffer
      reader.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对象ArrayBuffer
      reader.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-0cba8c508099
    mime: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对象ArrayBuffer
            reader.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)
        }
    })
}
// #endif

function 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({// 【重点来啦】人家自提供的转码API
            filePath: 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-PLUS
    else if (plus.io) {
        return H5PlusReadFile(filePath,mimeType);
    }
        // #endif
    // #ifdef H5
    else if (XMLHttpRequest) {
        return H5ReadBlobUrl(filePath,mimeType);
    }
    // #endif
    else {
        throw new Error('不支持的平台');
    }
};

实际运行效果

H5平台

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

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

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

其他场景有条件再测试。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电动汽车充电负荷时空分布预测(matlab)

目录 1 主要内容 交通网-配电网交互模型 动态交通路网模型 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序参考《基于动态交通信息的电动汽车充电负荷时空分布预测》和《基于动态交通信息的电动汽车充电需求预测模型及其对配网的影响分析》文献模型&#xff0c;考虑…

Py之ydata-profilin:ydata-profiling的简介、安装、使用方法之详细攻略

Py之ydata-profilin&#xff1a;ydata-profiling的简介、安装、使用方法之详细攻略 目录 ydata-profiling的简介 1、主要特点 2、案例应用 (1)、比较数据集、对时序数据集进行分析、对大型数据集进行分析、处理敏感数据、数据集元数据和数据字典、自定义报告的外观、不同类型…

yolov5-tracking-xxxsort yolov5融合六种跟踪算法(一)--环境配置CPU版本

本次开源计划主要针对大学生无人机相关竞赛的视觉算法开发。 开源代码仓库链接&#xff1a;https://github.com/zzhmx/yolov5-tracking-xxxsort.git 如果需要配置GPU版本环境可以查看我的这篇博客&#xff1a;yolov5-tracking-xxxsort yolov5融合六种跟踪算法&#xff08;一&am…

动态表格 点击单元格查看完整内容

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>分享收藏</title><script src"https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script><style…

Java零基础 - 逻辑运算符

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一个人虽可以走的更快&#xff0c;但一群人可以走的更远。 我是一名后…

[word] word带圈数字20以上 #笔记#笔记

word带圈数字20以上 办公中有时候需要用到带圈数字&#xff0c;超过20的数字就不能直接编辑了&#xff0c;那么20以上带圈数字要怎么输入呢&#xff1f;其实通过小技巧就能完成的&#xff0c;接下来就给大家介绍下呢&#xff0c;一起看看吧&#xff01; 20以上带圈数字输入技巧…

LaunchPad 市场的复苏,Penpad 成新兴生力军

以 Fair Launch 为主要启动方式的铭文市场的爆发&#xff0c;推动了 LaunchPad 市场的复苏&#xff0c;绝多数所铭文项目都能通过 Fairr Launch 的方式筹集资金实现启动&#xff0c;该赛道的爆发不仅推动了数百亿美元的热钱开始在链上不断涌动&#xff0c;同时也进一步形成了新…

String为什么是不可变的?

一、String字符串类型的数据结构 首先&#xff0c;String类是由 final 关键字修饰&#xff0c;这说明String 不可被继承。其次&#xff0c;由源代码可以看出String的成员字段value是一个char[ ]数组&#xff0c;在后面所有的String方法里都不提供修改Array数组的方法&#xff0…

torch.manual_seed(233333)

torch.manual_seed&#xff08;233333&#xff09; 介绍报错信息解决问题总结 介绍 这是在使用GPT-SoVITS时运行缺失pytorch导致报的错 报错信息 Traceback (most recent call last): File “D:\vits\GPT-SoVITS-beta\GPT-SoVITS-beta0217\webui.py”, line 10, in torch.m…

文件上传漏洞--Upload-labs--Pass17--条件竞争

一、条件竞争原理&#xff08;结合代码审计&#xff09; 1、首先进行代码审计&#xff0c;查看源代码。 我们可知&#xff0c;将文件上传至服务器后&#xff0c;不会被立即删除&#xff0c;而是做短暂的停留&#xff0c;中间会有一小部分时间差&#xff0c;这部分时间差是代码…

STM32使用软件SPI协议操作TFT18彩屏

时间记录&#xff1a;2024/2/20 一、SPI协议介绍 &#xff08;1&#xff09;SPI设备通过4根线进行通信&#xff0c;CS片选线&#xff0c;选择从设备&#xff0c;SCK时钟线&#xff0c;由主设备产生时钟&#xff0c;主机MOSI线连从机MISO线&#xff0c;由主机向从机发送信息&am…

HighTec编译器系列之01新建工程

HighTec编译器系列之01新建工程 继上篇《Hightec编译器系列之白嫖就是爽》小T告诉大家如何白嫖HighTec编译器长达一年之久之后&#xff0c;今天小T告诉大家如何进行HighTec编译器IDE的基础操作-即新建HighTec工程。 以下是本期内容的行文大纲&#xff1a; S1&#xff1a;创建…

Cesium for Unreal 从源码编译到应用——插件编译

一、安装环境 Unreal Engine 5.3 CMake 3.17.5 Microsoft Visual Studio 2019 二、源码准备 下载cesium-unreal-samples工程。 git clone https://github.com/CesiumGS/cesium-unreal-samples.git 然后在工程目录创建Plugins文件夹&#xff0c;并下载cesium-unreal工程。 …

java常用应用程序编程接口(API)——Objects类和包装类

前言&#xff1a; Object类和Objects类是完全不同的两个类&#xff0c;之前有说过Object类&#xff0c;这次说一下Objects类。打好基础&#xff0c;daydayup! Object类可以看这篇&#xff1a;java常用应用程序编程接口&#xff08;API&#xff09;——Object类概述及常用方法 O…

IIC通信驱动硬件编程 (1)

1、IIC协议基础 I2C( IIC )属于两线式串行总线&#xff0c;由飞利浦公司开发用于微控制器(MCU)和外围设备(从设备)进行通信的一种总线&#xff0c;属于一主多从即一个主设备(Master)&#xff0c;多个从设备(Slave))的总线结构&#xff0c;总线上的每个设备都有一个特定的设备地…

MR(混合现实)系统的开发流程

MR&#xff08;混合现实&#xff09;系统是一种将虚拟信息与真实世界环境相结合的技术&#xff0c;通过头戴式显示器、智能手机等设备将虚拟对象叠加在用户的真实感知中。它可以让用户与虚拟对象进行互动&#xff0c;并在真实环境中观察虚拟对象的行为。MR&#xff08;混合现实…

this的指向问题总结

this一般会出现在函数里面&#xff0c;但是一般情况下只有在函数被调用执行时&#xff0c;才能确定this指向哪个对象。一般情况下this是指调用函数的对象。 1.在全局作用域下或者普通函数中this的指向一般都是window对象 window.fn&#xff08;&#xff09;&#xff0c;普通函…

​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】

欢迎来CILMY23的博客喔&#xff0c;本期系列为​【C语言】长篇详解&#xff0c;字符系列篇3-----strstr&#xff0c;strtok&#xff0c;strerror字符串函数的使用【图文详解​】&#xff0c;图文讲解各种字符串函数&#xff0c;带大家更深刻理解C语言中各种字符串函数的应用&am…

35年的卓越成就:威步在网络安全和软件授权领域持续领先

1989-2023&#xff1a;威步成立35年里程碑。这35年中&#xff0c;公司始终致力于业务连续性、技术进步和团队凝聚力。 ​全球信任与在地优势&#xff1a;威步凭借其全球渠道合作伙伴网络&#xff0c;确保国际客户像信赖本地优质企业一样信赖他们。 传统与创新&#xff1a;威步…

Solidworks:焊件(型材)结构构件设计

焊件&#xff08;型材&#xff09;结构构件设计是Solidworks的一大特色。使用这一功能&#xff0c;能够体会到这款软件的架构设计在逐步递进增加软件功能方面做出的特别努力。 设计一个三角形框架 正面&#xff1a; 换个角度观察&#xff1a; 再来一个练习&#xff0c;包含…