Skip to content

Instantly share code, notes, and snippets.

@iamxiyang
Created December 11, 2022 03:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iamxiyang/33d539355c6b22d17c55037fe7b3a67b to your computer and use it in GitHub Desktop.
Save iamxiyang/33d539355c6b22d17c55037fe7b3a67b to your computer and use it in GitHub Desktop.
uniapp 读取文件 ArrayBuffer 获取 SHA 值,兼容 H5、小程序、APP
import { lib as CryptoLib, SHA256 } from 'crypto-js'
const arrayBufferToWordArray = (ab: any) => {
const i8a = new Uint8Array(ab)
const a = []
for (let i = 0; i < i8a.length; i += 4) {
a.push((i8a[i] << 24) | (i8a[i + 1] << 16) | (i8a[i + 2] << 8) | i8a[i + 3])
}
return CryptoLib.WordArray.create(a, i8a.length)
}
// #ifdef H5
// 通过blob:url读取实际的blob数据
// 参考:https://ask.dcloud.net.cn/question/75697
const blobURLToBlob = (url: string) => {
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: string) => {
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)
}
})
}
// #endif
// #ifdef APP-PLUS
// 通过plus.io读取文件的ArrayBuffer数据
const h5PlusReadFileArrayBuffer = (filePath: string) => {
return new Promise((resolve, reject) => {
try {
plus.io.resolveLocalFileSystemURL(
filePath,
function (entry: any) {
entry?.file(function (file: any) {
// @ts-ignore
const fileReader = new plus.io.FileReader()
fileReader.readAsDataURL(file, 'utf-8')
fileReader.onloadend = function (evt: any) {
const result = {
// 参考:https://www.freesion.com/article/40591516652/
base64: evt.target.result.split(',')[1],
size: file.size,
}
resolve(uni.base64ToArrayBuffer(result.base64))
}
})
},
function (error) {
reject(error)
},
)
} catch (error) {
reject(error)
}
})
}
// #endif
const getFileArrayBuffer = async (filePath: string) => {
if (uni.canIUse('getFileSystemManager') && uni.getFileSystemManager) {
const fs = uni.getFileSystemManager()
return fs.readFileSync(filePath)
}
// #ifdef APP-PLUS
else if (plus.io) {
return h5PlusReadFileArrayBuffer(filePath)
}
// #endif
// #ifdef H5
else if (XMLHttpRequest) {
return h5ReadBlobUrlArrayBuffer(filePath)
}
// #endif
else {
throw new Error('不支持的平台')
}
}
export const getFileSha256 = async (filePath: string) => {
if (!filePath) return Promise.reject('缺少文件路径')
const arrayBuffer = await getFileArrayBuffer(filePath)
return SHA256(arrayBufferToWordArray(arrayBuffer)).toString()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment