You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 13:17:41