React前端上传图片到Pinata IPFS报fs.createReadStream不存在错误如何解决
问题根因
fs是Node.js服务端专属的内置模块,仅能在Node运行环境中调用,你的React应用运行在浏览器端,浏览器没有提供fs相关API,因此调用fs.createReadStream会直接报错。你当前用的是Pinata官方提供的服务端上传示例代码,不能直接迁移到前端使用。
无fs模块的修复方案
不需要依赖fs模块,直接使用前端文件选择组件获取的原生File对象上传即可,修改逻辑如下:
- 调整
pinFileToIPFS方法入参,从接收文件路径改为接收File对象 - 移除所有
fs模块相关的引入和调用 - 删除手动设置的
Content-Type请求头,浏览器会自动生成multipart/form-data对应的正确boundary值,手动配置反而容易引发请求格式错误 - 额外安全提示:前端直接暴露Pinata的API密钥会导致密钥泄露,恶意用户可滥用你的Pinata存储配额,生产环境建议将上传逻辑放在自有后端服务,前端仅向后端传输文件,由后端调用Pinata接口完成上传。
修改后的完整代码:
require('dotenv').config(); const axios = require('axios'); const key = process.env.REACT_APP_PINATA_KEY; const secret = process.env.REACT_APP_PINATA_SECRET; // 入参改为用户上传的File对象,而非文件路径 export const pinFileToIPFS = async (file) => { const url = "https://api.pinata.cloud/pinning/pinFileToIPFS"; let data = new FormData(); // 直接追加File对象,不需要用fs读取 data.append('file', file); return axios.post(url, data, { maxContentLength: 'Infinity', headers: { // 不要手动设置Content-Type,浏览器会自动处理 'pinata_api_key': key, 'pinata_secret_api_key': secret } }) .then(function (response) { return { success: true, pinataUrl: "https://gateway.pinata.cloud/ipfs/" + response.data.IpfsHash }; }) .catch(function (error) { console.log(error) return { success: false, message: error.message, } }); };
React组件调用示例:
function UploadComponent() { const handleFileChange = async (e) => { const selectedFile = e.target.files[0]; if (!selectedFile) return; const uploadRes = await pinFileToIPFS(selectedFile); if (uploadRes.success) { console.log('上传成功,IPFS地址:', uploadRes.pinataUrl); } else { console.log('上传失败:', uploadRes.message); } } return <input type="file" onChange={handleFileChange} accept="image/*" /> }
内容的提问来源于stack exchange,提问作者arefin
相关产品推荐
相关产品推荐

