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

React类组件使用Pinata上传图片至IPFS报错求助

在React类组件中使用Pinata上传图片到IPFS的正确实现

问题场景

我尝试用Pinata将图片上传至IPFS,但遇到多个报错。以下是我的两个核心函数:

捕获文件的函数

captureFile = (e) => {
  console.log(e.target.files[0]);

  if (e.target.files[0]) {
    const file = e.target.files[0];
    const reader = new window.FileReader();
    
    reader.readAsArrayBuffer(file);
    reader.onloadend = () => {
      
      const buffer = Buffer.from(reader.result);
      const fileName = file.name;

      console.log('File Name:', fileName);
      
    
      this.setState({ 
        
        file,
        buffer,
        fileName, 
      });
    };
  }
};

上传至IPFS的函数

async uploadImageToIPFS(buffer, fileName) {
    try {
      const { apiKey, apiSecret } = this.state;
      const pinata = new pinataSDK(apiKey, apiSecret);
  
      const options = {
        pinataMetadata: {
          name: fileName,
        },
        pinataOptions: {
          cidVersion: 0,
        },
      };
  
      // Upload the file to IPFS using the provided buffer
      const result = await pinata.pinFileToIPFS(buffer, options);
      
      console.log(result.IpfsHash);
      console.log('IPFS Hash:', result.IpfsHash);
      return result.IpfsHash;
    } catch (error) {
      console.error('Error uploading to IPFS:', error);
      throw error;
    }
  }

我尝试了三种操作,都出现问题:

  • 传入Buffer对象时,报错:Error uploading to IPFS: Error: readStream is not a readable stream or form data
  • 传入file对象时,报错:Error uploading to IPFS: TypeError: source.on is not a function
  • 改用pinJSONToIPFS方法传入Buffer,虽成功获取IPFS哈希,但查看时显示的是Buffer对象而非图片。

需要找到正确实现方式,成功上传图片并能正常查看。

解决方案

问题核心在于浏览器环境下的参数适配:Pinata的pinFileToIPFS在浏览器中需要接收FormData对象,而非Node.js风格的Buffer或原始File对象。

修改后的实现步骤

  1. 简化文件捕获逻辑,直接保留File对象即可
  2. 重构上传函数,用FormData包装文件后再传递给Pinata SDK

修改后的captureFile函数

captureFile = (e) => {
  if (e.target.files[0]) {
    const file = e.target.files[0];
    this.setState({ 
      file,
      fileName: file.name 
    });
  }
};

修改后的uploadImageToIPFS函数

async uploadImageToIPFS(file, fileName) {
  try {
    const { apiKey, apiSecret } = this.state;
    const pinata = new pinataSDK(apiKey, apiSecret);

    // 构建符合浏览器上传要求的FormData
    const formData = new FormData();
    formData.append('file', file, fileName);

    const options = {
      pinataMetadata: {
        name: fileName,
      },
      pinataOptions: {
        cidVersion: 0,
      },
    };

    const result = await pinata.pinFileToIPFS(formData, options);
    console.log('IPFS Hash:', result.IpfsHash);
    return result.IpfsHash;
  } catch (error) {
    console.error('Error uploading to IPFS:', error);
    throw error;
  }
}

关键说明

  • 浏览器环境没有Node.js的可读流,FormData是标准的文件上传格式,Pinata SDK在浏览器端会正确解析它
  • 无需用FileReader转换为ArrayBuffer再转Buffer,直接使用input获取的File对象即可,FormData会自动处理文件编码
  • 调用上传函数时,直接传入this.state.file和this.state.fileName即可

内容的提问来源于stack exchange,提问作者Syed Rabeet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 22:12:40