从NodeJS上传Buffer至BackBlaze后图片损坏问题排查
问题分析与修复方案
上传图片损坏的核心原因是带前缀的base64字符串直接转换Buffer,以及错误使用Web Crypto API计算哈希。以下是具体修复步骤:
1. 移除base64前缀
readAsDataURL返回的字符串包含data:[mime-type];base64,前缀,直接转换Buffer会把这段非图片内容也写入文件,导致图片损坏。必须先剥离前缀。
2. 替换Web Crypto API为Node.js原生crypto模块
Node.js环境下crypto.subtle.digest并非最优选择,使用原生crypto.createHash更稳定且符合Node.js生态。
修改后的代码
获取文件Blob函数(修复前缀处理)
async function GetFileBlob(url: string, callback: any) { await fetch(url) .then(response => response.blob()) .then(blob => { const reader = new FileReader(); reader.readAsDataURL(blob); reader.onloadend = function (e) { const base64Str = e.target!.result.toString(); // 移除base64前缀 const pureBase64 = base64Str.split(',')[1]; callback(pureBase64); }; }); }
上传文件函数(修复Buffer转换与哈希计算)
import crypto from 'crypto'; // 引入Node.js原生crypto模块 export async function UploadFile(req: any, res: any, next: any) { let image: any = req.body.FrontImage; // 确保前端传来的base64已经移除前缀,若没处理则这里再做一次 const pureBase64 = image.includes(',') ? image.split(',')[1] : image; let data: any = await GetUploadUrl(async (data) => { try { // 用纯净的base64转换Buffer const fileContent = Buffer.from(pureBase64, 'base64'); // 使用Node.js原生crypto计算SHA-1哈希 const hashHex = crypto.createHash('sha1').update(fileContent).digest('hex'); // 上传到BackBlaze let msg: string, detail: string; try { const response = await fetch(data.uploadUrl, { method: "POST", mode: "cors", body: fileContent, headers: { "Content-Type": "b2/x-auto", "Authorization": data.authorizationToken, "X-Bz-File-Name": 'testfile10.jpeg', "X-Bz-Content-Sha1": hashHex, }, }); if (response.status >= 200 && response.status < 300) { msg = `${response.status} response from B2 API. Success!`; } else if (response.status >= 400) { msg = `${response.status} error from B2 API.`; } else { msg = `Unknown error.`; } detail = await response.text(); } catch (error) { console.error("Fetch threw an error:", error) msg = `Fetch threw "${error}" - see the console and/or network tab for more details` detail = error.stack; } next(); } catch (err) { console.log('Error getting bucket:', err); } }); }
额外检查点
- 确认React Native端上传的图片base64是否已正确处理(避免重复前缀)
- 验证
fileContent的长度是否符合原图片大小(可通过fileContent.length对比原文件字节数) - 检查BackBlaze返回的响应详情,若哈希不匹配会返回错误,可据此排查转换问题
内容的提问来源于stack exchange,提问作者Warona
相关产品推荐
相关产品推荐

