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

如何获取<input>文件真实路径?Pinata IPFS上传假路径问题

解决Pinata IPFS文件上传的假路径问题

问题核心是浏览器出于安全机制,不会暴露用户本地文件的真实路径,input[type="file"].value返回的C:\fakepath\xxx是浏览器伪造的路径,无法直接用于后端的fs.createReadStream读取。正确的做法是传输文件内容而非路径,具体方案如下:


1. 前端修改:传输文件内容而非路径

不要获取file.value,而是直接获取<input>选中的File对象,通过Socket.IO传输文件内容(支持二进制或FormData格式):

<body>
  <input type="file" id="file-upload">
  <script src="/socket.io/socket.io.js"></script>
  <script>
    const socket = io();
    const fileInput = document.getElementById("file-upload");
    
    fileInput.addEventListener("change", (e) => {
      const selectedFile = e.target.files[0];
      if (!selectedFile) return;

      // 方式:用FormData封装文件,直接通过Socket.IO发送
      const formData = new FormData();
      formData.append("uploadFile", selectedFile);
      
      socket.emit("send-file-to-pinata", {
        fileName: selectedFile.name,
        fileData: formData
      });
    });
  </script>
</body>

2. 后端修改:接收文件内容并上传到Pinata

后端不再接收路径,而是接收前端传来的文件内容,将其转为可读流或直接用Buffer封装进FormData,再调用Pinata API:

const io = require('socket.io')(server);
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const path = require('path');
const os = require('os');

// 处理Socket.IO传来的文件
io.on('connection', (socket) => {
  socket.on('send-file-to-pinata', async ({ fileName, fileData }) => {
    try {
      // 临时存储文件(可选,也可直接用Buffer处理)
      const tempFilePath = path.join(os.tmpdir(), `${Date.now()}-${fileName}`);
      const writeStream = fs.createWriteStream(tempFilePath);
      
      // 解析FormData并写入临时文件
      fileData.pipe(writeStream);
      await new Promise((resolve, reject) => {
        writeStream.on('finish', resolve);
        writeStream.on('error', reject);
      });

      // 调用上传函数
      const uploadResult = await pinToPinata(
        '你的Pinata API Key',
        '你的Pinata Secret Key',
        tempFilePath,
        fileName
      );

      // 删除临时文件
      fs.unlinkSync(tempFilePath);
      
      socket.emit('upload-success', uploadResult.data);
    } catch (err) {
      socket.emit('upload-error', err.message);
    }
  });
});

// 优化后的Pinata上传函数
async function pinToPinata(apiKey, secretKey, filePath, fileName) {
  const url = 'https://api.pinata.cloud/pinning/pinFileToIPFS';
  const formData = new FormData();
  
  // 添加文件流到FormData
  formData.append('file', fs.createReadStream(filePath), { filename: fileName });
  
  return axios.post(url, formData, {
    maxBodyLength: Infinity,
    headers: {
      // 自动生成Content-Type和boundary,避免手动设置出错
      ...formData.getHeaders(),
      pinata_api_key: apiKey,
      pinata_secret_api_key: secretKey
    }
  });
}

关键说明

  • 浏览器安全限制:永远不要试图获取本地文件的真实路径,这是浏览器的安全保护机制,无法绕过。
  • 文件传输方式:除了FormData,也可以用FileReader将文件转为ArrayBuffer后传输,后端再转为Buffer处理。
  • 临时文件处理:如果不想用临时文件,可直接将前端传来的Buffer添加到FormData中(formData.append('file', buffer, { filename: fileName })),省去磁盘IO步骤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:58:02