通过nft.storage API上传图片到IPFS:curl可用但JS代码失效问题
问题核心原因
- curl命令里的
@文件路径是curl专属语法,作用是自动读取路径对应文件的二进制内容作为请求体,JS原生语法不支持该规则,你直接传入字符串"@home/myfolder/file.png"会直接把这段文本作为请求体上传,因此IPFS上存储的是文本内容而非图片二进制。 - 代码存在变量名错误:你声明了存储内容的变量叫
data,但xhr.send()传入的是未定义的file变量。 - 浏览器端JS受同源策略和沙箱限制,无法直接读取本地/服务器磁盘的任意路径文件,需要先获取到图片的二进制数据才能上传。
修复方案
根据你的代码运行环境选择对应方案:
场景1:代码运行在Node.js服务端(推荐,适配上传服务器本地存储图片的需求)
首先读取服务器本地文件的二进制流,再发起上传请求,示例代码如下:
const fs = require('fs') const https = require('https') // 替换为你的服务器本地图片路径 const filePath = '/home/myfolder/file.png' // 替换为你的nft.storage API密钥 const apiKey = 'eyJhbGciOiJIUzI1NiIsInR5cC....' // 读取文件二进制内容 const fileContent = fs.readFileSync(filePath) const options = { hostname: 'api.nft.storage', path: '/upload', method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'image/png', 'Content-Length': fileContent.length } } const req = https.request(options, (res) => { let responseData = '' res.on('data', (chunk) => { responseData += chunk }) res.on('end', () => { console.log('上传成功,返回结果:', JSON.parse(responseData)) }) }) req.on('error', (e) => { console.error('请求错误:', e) }) // 传入文件二进制内容发送请求 req.write(fileContent) req.end()
如果使用axios可以简化为:
const fs = require('fs') const axios = require('axios') const filePath = '/home/myfolder/file.png' const apiKey = 'eyJhbGciOiJIUzI1NiIsInR5cC....' const fileContent = fs.readFileSync(filePath) axios.post('https://api.nft.storage/upload', fileContent, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'image/png' } }).then(res => { console.log('上传结果', res.data) }).catch(err => { console.error('上传失败', err) })
场景2:代码必须运行在浏览器端
需要先将服务器上的图片以二进制格式请求到浏览器端,再上传到nft.storage,示例代码如下:
document.getElementById("test").addEventListener("click", async function() { const uploadUrl = "https://api.nft.storage/upload"; // 替换为你的服务器上图片的公网可访问URL const serverImgUrl = "https://your-domain.com/file.png"; // 替换为你的nft.storage API密钥 const apiKey = "eyJhbGciOiJIUzI1NiIsInR5cC...."; try { // 先从你的服务器拉取图片二进制数据 const imgRes = await fetch(serverImgUrl) const imgBlob = await imgRes.blob() const xhr = new XMLHttpRequest(); xhr.open("POST", uploadUrl); xhr.setRequestHeader("Authorization", `Bearer ${apiKey}`); xhr.setRequestHeader("Content-Type", "image/png"); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { console.log(xhr.status); console.log(xhr.responseText); } }; // 传入图片Blob对象发送请求 xhr.send(imgBlob); } catch (err) { console.error('处理失败', err) } });
注意:浏览器端运行需要你的服务器配置跨域资源共享(CORS)规则,允许当前页面的域名请求图片资源,否则会被跨域策略拦截。
内容的提问来源于stack exchange,提问作者moyer48095
相关产品推荐
相关产品推荐

