如何从Uint8Array二进制数据中获取对应的MIME类型?
如何从Uint8Array中获取MIME类型?
你当前从IPFS获取Uint8Array的代码如下:
import all from 'it-all' import { concat as uint8ArrayConcat } from 'uint8arrays/concat' const hash = 'QmRW5tvGURXTcWwch5hQyeaEVdmeU3RGjyBo8cLZhmhS9x' const response = uint8ArrayConcat(await all(ipfs.cat(hash))) console.log('response', response) // 输出: Uint8Array(6746687)
你目前通过提取文件头魔数匹配MIME类型的实现:
switch (header) { case '89504e47': type = 'image/png'; break; case '47494638': type = 'image/gif' break case 'ffd8ffe0': case 'ffd8ffe1': case 'ffd8ffe2': case 'ffd8ffe3': case 'ffd8ffe8': type = 'image/jpeg' break default: type = 'unknown' break }
更简便的实现方案
方案1:无依赖通用封装(推荐)
无需写大量switch分支,把魔数和MIME的对应关系做成配置表,统一匹配逻辑即可,后续扩展新类型只需要加配置:
// 魔数映射表,key为十六进制魔数前缀,value为对应MIME类型 const mimeMagicMap = new Map([ ['89504E47', 'image/png'], ['47494638', 'image/gif'], ['FFD8FF', 'image/jpeg'], // jpeg匹配前3字节即可,无需多分支判断 ['25504446', 'application/pdf'], ['504B0304', 'application/zip'] // 按需扩展其他类型的魔数规则即可 ]) function getMimeType(uint8arr) { // 提取前4字节转十六进制字符串,覆盖绝大多数常用类型的魔数长度 const header = uint8arr.slice(0,4).reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '' ).toUpperCase() // 前缀匹配魔数 for (const [magic, mimeType] of mimeMagicMap) { if (header.startsWith(magic)) return mimeType } return 'unknown' } // 直接调用获取类型 const fileType = getMimeType(response)
方案2:浏览器环境用内置API简化
如果代码运行在支持Blob的前端环境,可以直接用内置能力辅助检测:
function getMimeType(uint8arr) { const blob = new Blob([uint8arr]) return blob.type || 'unknown' }
注意该方案对部分冷门格式识别准确率不如魔数匹配,对识别准确率要求高的场景建议搭配方案1的魔数校验一起使用。
内容的提问来源于stack exchange,提问作者Narnik Gamarnik
相关产品推荐
相关产品推荐

