Infura.io IPFS网关认证后无法上传,报ipfsHash[0]未定义错误
问题:Infura IPFS认证后上传失败,报错
TypeError: Cannot read properties of undefined (reading '0') 背景
2022年10月前,Infura IPFS允许无需认证上传,原有代码可正常运行。添加认证后,无法上传/固定内容,触发报错:
TypeError: Cannot read properties of undefined (reading '0')
位置:src/App.js:287行myMetadata.image = this.state.web3ctx.ipfsGateway + ipfsHash[0].hash;
用户已排查:调整认证信息、验证主机地址(曾怀疑需用专属地址nftpatent.infura-ipfs.io,但资料显示只需提供认证),认为问题出在认证环节。
相关代码
原有无认证ipfs.js
const IPFS = require('ipfs-api'); const ipfs = new IPFS({host: 'ipfs.infura.io', port: 5001, protocol: 'https'}); export default ipfs;
修改后带认证的ipfs.js
const projectId ='ZZZZZZZZZZZZZZz'; const projectSecret='ZXXXZZXXXXXXXXXX'; const auth = 'Bearer ' + (projectId + ':' +projectSecret); const ipfs = new IPFS({ host: 'ipfs.infura.io', //host: 'nftpatent.infura-ipfs.io/', port: 5001, protocol: 'https', headers: { authorization: auth, } });
App.js上传逻辑代码
// save document to IPFS,return its hash#, and set hash# to state // setState by setting ipfsImageHash to ipfsImageHash[0].hash if (this.state.myToken.imageBuffer && this.state.myToken.imageBuffer.length > 0) { await ipfs.add(this.state.myToken.imageBuffer, (err, ipfsHash) => { console.log('IPFS hash: ' + ipfsHash + ', error: ' + err); let myMetadata = JSON.parse(JSON.stringify(this.state.myToken.metadataBuffer)); myMetadata.image = this.state.web3ctx.ipfsGateway + ipfsHash[0].hash; this.setState({ myToken: { ...this.state.myToken, ipfsImageHash: ipfsHash[0].hash, ipfsImageUrl: myMetadata.image, metadataBuffer: myMetadata, imageBuffer: '' }, selectedTab: 'Metadata' }); }) } else if (this.state.myToken.metadataBuffer && this.state.myToken.metadataBuffer.toString().length > 0) { await ipfs.add(Buffer.from(JSON.stringify(this.state.myToken.metadataBuffer)), (err, ipfsHash) => { console.log('IPFS hash: ' + ipfsHash + ', error: ' + err); this.setState({ myToken: { ...this.state.myToken, ipfsMetadataHash: ipfsHash[0].hash, ipfsMetadataUrl: this.state.web3ctx.ipfsGateway + ipfsHash[0].hash }, selectedTab: 'Metadata' }); }) } else { console.log('file could not be found: ' + JSON.stringify(this.state.myToken.metadataBuffer, null, 2)); return 1; }
问题分析与解决
1. 异步调用逻辑错误
你同时混用了await和回调函数,但ipfs.add使用回调时不会返回Promise,await完全不起作用,导致代码在未拿到ipfsHash时就执行后续操作,自然会出现ipfsHash为undefined的情况。
改成Promise风格调用:
// 图片上传部分修改 try { const ipfsHash = await ipfs.add(this.state.myToken.imageBuffer); console.log('IPFS hash:', ipfsHash); let myMetadata = JSON.parse(JSON.stringify(this.state.myToken.metadataBuffer)); myMetadata.image = this.state.web3ctx.ipfsGateway + ipfsHash[0].hash; this.setState({ myToken: { ...this.state.myToken, ipfsImageHash: ipfsHash[0].hash, ipfsImageUrl: myMetadata.image, metadataBuffer: myMetadata, imageBuffer: '' }, selectedTab: 'Metadata' }); } catch (err) { console.error('图片上传失败:', err); } // 元数据上传同理修改 try { const ipfsHash = await ipfs.add(Buffer.from(JSON.stringify(this.state.myToken.metadataBuffer))); console.log('IPFS hash:', ipfsHash); this.setState({ myToken: { ...this.state.myToken, ipfsMetadataHash: ipfsHash[0].hash, ipfsMetadataUrl: this.state.web3ctx.ipfsGateway + ipfsHash[0].hash }, selectedTab: 'Metadata' }); } catch (err) { console.error('元数据上传失败:', err); }
2. 认证格式错误
Infura IPFS要求使用Basic认证,而非Bearer。正确的认证生成方式是将projectId:projectSecret做Base64编码,再添加Basic前缀:
const projectId = 'ZZZZZZZZZZZZZZz'; const projectSecret = 'ZXXXZZXXXXXXXXXX'; // 正确生成Basic认证字符串 const auth = 'Basic ' + Buffer.from(`${projectId}:${projectSecret}`).toString('base64');
3. 主机地址与端口验证
- 若使用专属网关,主机地址改为
nftpatent.infura-ipfs.io,端口可改为443(HTTPS默认端口),或直接省略port配置; - 若使用公共网关,
ipfs.infura.io可正常使用,确保认证格式正确即可。
修改后的ipfs.js示例:
const IPFS = require('ipfs-api'); const projectId = 'ZZZZZZZZZZZZZZz'; const projectSecret = 'ZXXXZZXXXXXXXXXX'; const auth = 'Basic ' + Buffer.from(`${projectId}:${projectSecret}`).toString('base64'); const ipfs = new IPFS({ host: 'ipfs.infura.io', // 或替换为专属地址'nftpatent.infura-ipfs.io' port: 5001, protocol: 'https', headers: { authorization: auth, } }); export default ipfs;
内容的提问来源于stack exchange,提问作者Ecorpnu
相关产品推荐
相关产品推荐

