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对象。
修改后的实现步骤
- 简化文件捕获逻辑,直接保留File对象即可
- 重构上传函数,用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
相关产品推荐
相关产品推荐

