业务需求和bug

业务需求

获取图片文件的md5值(图片通过uni.chooseImage上传),要兼容浏览器和微信小程序端。(本文使用浏览器环境为Chrome浏览器)

bug描述

浏览器端使用的 FileReader() 对象的 reader.readAsArrayBuffer(file) 方法转成 Arraybuffer,再使用 crypto-js 转成 md5。

微信小程序使用 FileSystemManager.readFile() API读取为 ArrayBuffer,再使用 crypto-js 转成 md5。

微信小程序无论什么图,获取到的md5都是 487f7b22f68312d2c1bbc93b1aea445b,浏览器端正常。

这部分代码大概如下:(从项目中摘取出来的,没真实运行,算是伪代码)

import CryptoJS from "crypto-js"; 

let arraybuffer = null
// 浏览器
// #ifdef WEB
const reader = new FileReader();
reader.onload = (e) => {
    // 获取到的 ArrayBuffer
    console.log(e.target.result)
    arraybuffer = e.target.result
};

reader.onerror = (err) => {
    console.log(err)

};

// 读取文件为 ArrayBuffer
reader.readAsArrayBuffer(file);
// #endif


// 微信小程序读取文件处理
// #ifdef MP-WEIXIN
const reader = uni.getFileSystemManager()
reader.readFile({
	filePath: file.path, // 这里填入文件路径
	encoding: "", // 留空,表示读取原始二进制数据
	success: (res) => {
        // 获取到的 ArrayBuffer
	    console.log(res.data)
        arraybuffer = e.target.result
	},
	fail: (err) => {
		console.error('读取文件失败', err);
	}
});
// #endif

// CryptoJS 转 md5
const wordArray = CryptoJS.lib.WordArray.create(arraybuffer);
const md5 = CryptoJS.MD5(wordArray).toString();

排错过程

打印 arraybuffer 和 wordArray

分别在两端打印了获取到的 arraybuffer 和 wordArray,乍一看都问题,仔细对比才发现,两边的arraybuffer 不太一样??导致 CryptoJS.lib.WordArray.create 创建的 WordArray 也不对,不细看都没发现。这直接导致了后面 WordArray 转 md5 出现 bug。

(所有图:黑底微信是小程序、白底是浏览器)

 wordArray 对比

目测两边一样

arraybuffer 对比

两边的 arraybuffer 看起来差不多,对象原型都是 ArrayBuffer。

( __proto__和 [[prototype]] 都是指原型对象,浏览器差异会有不同显示)

 

问题解决&结论

instanceof 查找原型链

instanceof 用于判断一个对象是否是某个构造函数的实例,会沿着对象的原型链去查找是否有 Constructor.prototype,如果有则返回 true,否则返回 false

为什么原型对象都一样,但是生成出来的 wordArray 不一样 ????,试了很多,最后终于通过 instanceof  找到了答案:

代码:

console.log('instanceof ArrayBuffer', arraybuffer instanceof ArrayBuffer);  

运行结果:

结论

微信小程序的原型对象 ArrayBuffer 非 JS 的原型对象 ArrayBuffer!!!!!!!!???

解决

手动将微信小程序原型对象设为JS 的原型对象,ArrayBuffer 尝试添加以下代码:

Object.setPrototypeOf(item.result, ArrayBuffer.prototype);

BUG解决,微信小程序 crypto-js 转 md5 结果正常。

PS:很痛苦的排错

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐