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

如何使用jQuery getJSON获取后端IPFS文件哈希并更新前端innerHTML

文件上传IPFS功能代码修复

现有代码核心问题

  • 逻辑冲突:同时写了浏览器端直连IPFS上传、后端代理上传两套逻辑,互相干扰
  • 请求方式错误:文件上传使用GET请求搭配$.getJSON,无法传输二进制文件内容,且GET请求没有请求体,后端req.files永远拿不到值
  • 异步语法错误:
    • 前端IpfsCore.create()是异步方法,未加await就调用后续方法会直接抛出异常
    • 后端saveFile方法没有return返回值,且混用回调风格的ipfs.add和async/await,接口无法返回真实的文件哈希
  • 选择器错误:jQuery获取元素写为$('file'),缺少ID选择器前缀#,无法选中文件输入框
  • 文件处理错误:直接JSON.stringify(file)序列化File对象,会丢失二进制内容,最终存到IPFS的只是文件元数据字符串,不是真实文件
  • 事件绑定逻辑混乱:clickme方法里重复绑定change事件,存在重复触发风险

修正后代码

后端 index.js

首先需要安装文件上传处理依赖:

npm install express-fileupload

修正后的服务端代码:

const express = require('express');
const fileUpload = require('express-fileupload');
const app = express();
// 注册文件上传中间件,支持最大500MB文件
app.use(fileUpload({
  limits: { fileSize: 500 * 1024 * 1024 },
}));

// 上传接口改为POST方法
app.post('/upload', async (req, res) => {
  try {
    if (!req.files || !req.files.file) {
      return res.status(400).json({ code: 400, msg: '未接收到上传文件' });
    }
    const file = req.files.file;
    // 直接传文件buffer给IPFS,不要JSON序列化
    const fileHash = await saveFile(file.data);
    res.json({ code: 200, hash: fileHash, fileType: file.mimetype, fileName: file.name });
  } catch (err) {
    console.log('上传失败:', err);
    res.status(500).json({ code: 500, msg: '上传失败' });
  }
})

async function saveFile(fileBuffer) {
  // 注意:这里需要提前初始化你服务端的ipfs节点实例,替换为你自己的初始化逻辑
  const result = await ipfs.add(fileBuffer);
  console.log('文件上传IPFS成功,CID:', result.cid.toString());
  return result.cid.toString();
}

app.listen(3000, () => {
  console.log('服务运行在3000端口');
})

前端 index.ejs

这里统一走后端代理上传逻辑,移除冗余的前端IPFS初始化代码,修正请求和DOM更新逻辑:

<!-- 不需要前端引ipfs-core,走后端上传即可 -->
<input type="file" id="file" accept="image/*,video/*,audio/*,application/pdf">
<div>文件名:<span id="fileNameOutput"></span></div>
<div>IPFS哈希:<span id="ipfs"></span></div>
<div id="filePreview"></div>

<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script>
// 页面加载完成后绑定事件
$(function() {
  $('#file').on('change', readfichier);
})

async function readfichier(e) {
  const file = e.target.files[0];
  if (!file) return;

  // 显示文件名
  $('#fileNameOutput').text(file.name);
  $('#ipfs').text('上传中...');
  $('#filePreview').html('');

  // 构造FormData传文件,不用GET请求
  const formData = new FormData();
  formData.append('file', file);

  try {
    // 用POST请求上传,不要用$.getJSON
    const res = await $.ajax({
      url: '/upload',
      type: 'POST',
      data: formData,
      processData: false,
      contentType: false,
      dataType: 'json'
    });

    if (res.code === 200) {
      // 更新哈希到页面
      $('#ipfs').text(res.hash);
      // 渲染文件预览
      renderPreview(res.hash, res.fileType);
    } else {
      $('#ipfs').text('上传失败:' + res.msg);
    }
  } catch (err) {
    $('#ipfs').text('上传请求失败');
    console.log(err);
  }
}

// 多格式文件预览渲染
function renderPreview(cid, fileType) {
  // 替换为你自己部署的IPFS网关地址
  const gatewayUrl = `/ipfs/${cid}`;
  let previewHtml = '';
  if (fileType.startsWith('image/')) {
    previewHtml = `<img src="${gatewayUrl}" style="max-width: 100%;" alt="预览图">`;
  } else if (fileType.startsWith('video/')) {
    previewHtml = `<video src="${gatewayUrl}" controls style="max-width: 100%;"></video>`;
  } else if (fileType.startsWith('audio/')) {
    previewHtml = `<audio src="${gatewayUrl}" controls></audio>`;
  } else if (fileType === 'application/pdf') {
    previewHtml = `<embed src="${gatewayUrl}" type="application/pdf" width="100%" height="600px">`;
  } else {
    previewHtml = `<a href="${gatewayUrl}" target="_blank">点击下载文件</a>`;
  }
  $('#filePreview').html(previewHtml);
}
</script>

注意事项

  • 服务端需要提前完成IPFS节点初始化,确保ipfs实例可用
  • 生产环境建议自己部署IPFS网关,不要依赖公共网关,保证文件访问稳定性
  • 如果需要前端直连IPFS上传,只需要把后端上传逻辑替换为前端正确初始化IPFS节点后上传即可,不需要调用后端接口,两种方案二选一即可,不要同时使用

内容的提问来源于stack exchange,提问作者JackDonMcLovin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 01:30:46