IPFS Pinata 服务不接受文件

IPFS Pinata service not accepting file

我有一个如下所示的代码,它从浏览器上传文件并保存在服务器中,一旦保存到服务器,我希望服务器连接到 Pinata API 所以文件也可以保存到IPFS节点。

  let data = new FormData();

                      const fileBuffer = Buffer.from(`./public/files/${fileName}`, 'utf-8');
                      data.append('file', fileBuffer, `${fileName}`);

                      axios.post('https://api.pinata.cloud/pinning/pinJSONToIPFS',
                          data,
                          {
                              headers: {
                                  'Content-Type': `multipart/form-data; boundary= ${data._boundary}`,
                                  'pinata_api_key': pinataApiKey,
                                  'pinata_secret_api_key': pinataSecretApiKey
                              }
                          }
                      ).then(function (response) {
                          console.log("FILE UPLOADED TO IPFS NODE", fileName);
                          console.log(response);
                      }).catch(function (error) {
                          console.log("FILE WASNT UPLOADED TO IPFS NODE", fileName);
                          console.log(error);
                      });

我遇到的问题是,在为我的文件创建缓冲区并将其包装在表单数据中后,pinata API returns 出现错误:

   data: {
      error: 'This API endpoint requires valid JSON, and a JSON content-type'
    }

如果我将数据转换为字符串,如 JSON.stringify(data) 并将内容类型更改为 application/json,文件缓冲区将作为字符串成功上传。

希望能解释清楚,得到解决。谢谢

您似乎正在尝试将文件上传到 pinJSONToIPFS 端点,该端点旨在纯粹用于通过请求正文传入的 JSON。

在你的情况下,我建议使用 Pinata 的 pinFileToIPFS endpoint

下面是一些基于其文档的示例代码,可能会有帮助:

//imports needed for this function
const axios = require('axios');
const fs = require('fs');
const FormData = require('form-data');

export const pinFileToIPFS = (pinataApiKey, pinataSecretApiKey) => {
    const url = `https://api.pinata.cloud/pinning/pinFileToIPFS`;

    //we gather a local file for this example, but any valid readStream source will work here.
    let data = new FormData();
    data.append('file', fs.createReadStream('./yourfile.png'));

    return axios.post(url,
        data,
        {
            maxContentLength: 'Infinity', //this is needed to prevent axios from erroring out with large files
            headers: {
                'Content-Type': `multipart/form-data; boundary=${data._boundary}`,
                'pinata_api_key': pinataApiKey,
                'pinata_secret_api_key': pinataSecretApiKey
            }
        }
    ).then(function (response) {
        //handle response here
    }).catch(function (error) {
        //handle error here
    });
};

将任何文件固定到 IPFS 的正确代码如下。

显然,连 Pinata 支持人员都不知道这一点。 您需要使用 属性 名称文件路径设置一个对象作为最后一个参数。名字无所谓,可以重复,可以和别人一样,也可以是唯一的。

const url = "https://api.pinata.cloud/pinning/pinFileToIPFS";
const fileContents = Buffer.from(bytes);
const data = new FormData();
data.append("file", fileContents, {filepath: "anyname"});
const result = await axios
    .post(url, data, {
        maxContentLength: -1,
        headers: {
            "Content-Type": `multipart/form-data; boundary=${data._boundary}`,
            "pinata_api_key": userApiKey,
            "pinata_secret_api_key": userApiSecret,
            "path": "somename"
        }
    });

使用 Pinata 在 IPFS 上上传文件的代码。

有两种方法可以在 Pinata 上上传 files/images。一个是 Pinata SDK,第二个是 pinFileToIPFS 端点。

如果您从 Next.js 上传文件,则无法使用 fs.createReadStream[=24= 将图像转换为二进制文件]。这些包支持节点端。因此,如果您想在 Pinata 上上传带有 Next.js 的文件,那么您可以使用此代码。

 // convert file into binary
      const data = new FormData();
      data.append("title", file.name);
      data.append("file", file);

     const url = "https://api.pinata.cloud/pinning/pinFileToIPFS";
        // pass binary data into post request
        const result = await axios.post(url, data, {
          maxContentLength: -1,
          headers: {
            "Content-Type": `multipart/form-data; boundary=${data._boundary}`,
            pinata_api_key: "your_pinata_key",
            pinata_secret_api_key:
              "your_pinata_secret",
            path: "somename",
          },
        });
        console.log("RESULT", result);