如何仅使用纯JavaScript将文件添加至IPFS?
NFT图片自动加载的IPFS方案(基于js-ipfs/ipfs-core/ipfs-http-client)
免费公共IPFS资源替代Infura
不用依赖收费的Infura服务,可选择以下免费方案:
- 公共网关:Cloudflare(
https://cloudflare-ipfs.com/ipfs/)、Dweb.link(https://dweb.link/ipfs/),直接通过网关URL拼接CID即可访问内容。 - 免费Pin服务:Pinata提供每月1GB存储+10GB带宽的免费额度,可用于固定NFT图片,避免内容从网络中消失。
各库实现代码示例
1. ipfs-http-client 连接公共节点
适合后端或前端场景,通过公共API节点获取内容,无需本地启动节点:
import { create } from 'ipfs-http-client'; // 连接Cloudflare公共IPFS API节点 const ipfsClient = create({ url: 'https://cloudflare-ipfs.com/api/v0/' }); async function loadNFTImage(cid) { try { const chunks = []; // 流式获取文件内容 for await (const chunk of ipfsClient.cat(cid)) { chunks.push(chunk); } const blob = new Blob(chunks); // 生成可直接用于img标签src的URL return URL.createObjectURL(blob); } catch (err) { console.error('IPFS节点请求失败,切换到网关访问:', err); // 网关兜底方案 return `https://cloudflare-ipfs.com/ipfs/${cid}`; } }
2. ipfs-core 本地轻节点
适合浏览器、桌面应用等客户端场景,去中心化程度更高,不依赖第三方网关:
import { create } from 'ipfs-core'; let ipfsNode; // 初始化本地IPFS节点(仅需一次) async function initLocalIPFS() { if (!ipfsNode) { ipfsNode = await create({ repo: 'nft-local-ipfs-repo', config: { Bootstrap: [ '/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN', '/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa' ] } }); } return ipfsNode; } async function loadNFTImageLocal(cid) { try { const ipfs = await initLocalIPFS(); const chunks = []; for await (const chunk of ipfs.cat(cid)) { chunks.push(chunk); } const blob = new Blob(chunks); return URL.createObjectURL(blob); } catch (err) { console.error('本地节点加载失败,切换到公共网关:', err); return `https://dweb.link/ipfs/${cid}`; } }
3. js-ipfs(旧版兼容)
若项目仍使用已维护的js-ipfs(注意该库已逐步被ipfs-core替代),可参考以下代码:
import IPFS from 'js-ipfs'; let ipfsInstance; async function initJSIPFS() { if (!ipfsInstance) { ipfsInstance = await IPFS.create({ repo: 'nft-js-ipfs-repo', config: { Bootstrap: [ '/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN' ] } }); } return ipfsInstance; } async function loadNFTImageJSIPFS(cid) { try { const node = await initJSIPFS(); const data = await node.cat(cid); const blob = new Blob([data]); return URL.createObjectURL(blob); } catch (err) { console.error('js-ipfs加载失败:', err); return `https://cloudflare-ipfs.com/ipfs/${cid}`; } }
优化建议
- 本地缓存:将已加载的NFT图片缓存到
localStorage或IndexedDB,重复访问时直接读取缓存,减少IPFS请求。 - 多网关降级:维护一个网关列表,请求失败时自动切换到下一个,提升可用性。
- 内容固定:使用免费Pin服务固定NFT图片CID,确保内容长期可访问,避免因节点离线导致加载失败。
内容的提问来源于stack exchange,提问作者N Y
相关产品推荐
相关产品推荐

