问题描述
我有一个如下所示的代码,它从浏览器上传文件并保存在服务器中,一旦保存到服务器,我希望服务器连接到 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 返回错误:
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 支持人员也不知道这一点。 您需要将属性名称为 filepath 的对象设置为最后一个参数。名称无关紧要,可以是重复的,可以与其他名称相同,也可以是唯一的。
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,{
maxContentLength: -1,headers: {
"Content-Type": `multipart/form-data; boundary=${data._boundary}`,"pinata_api_key": userApiKey,"pinata_secret_api_key": userApiSecret,"path": "somename"
}
});