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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 02:10:25