如何在JavaScript中POST multipart/form-data?图片上传格式报错
问题解决:Sanity图片上传提示“输入缓冲区包含不支持的图片格式”
错误原因
你在后端调用Sanity的assets.upload方法时,直接传入了formidable解析后的files对象——该对象只是上传文件的元数据容器,并非实际的图片文件内容(Buffer或流),导致Sanity无法识别图片格式。
解决方案
需要从formidable解析结果中提取实际的文件内容,再传给Sanity的上传接口。以下分formidable版本给出修正代码:
前端代码(小优化)
在input标签中限制仅接受图片类型,避免用户上传非图片文件:
export default function Component() { const handleSubmit = async (e: FormEvent<HTMLFormElement>) => { e.preventDefault(); const file = e.currentTarget[0]?.files[0]; if (!file) return; // 增加文件校验 const formdata = new FormData(); formdata.append("file", file); fetch("/api/uploadImage", { method: "POST", body: formdata, }) .then((res) => res.json()) .then((r) => console.log(r)) .catch((err) => console.log(err)); }; return ( <div> <form encType="multipart/form-data" onSubmit={handleSubmit}> {/* 限制仅接受图片文件 */} <input type="file" id="inputFile" name="avatar" accept="image/*" /> <button type="submit" className="rounded-md bg-indigo-500 px-4 py-1 text-white" > 选择图片 </button> </form> </div> ); }
后端代码(formidable v2版本)
import fs from 'fs'; import formidable from 'formidable'; // 导入你的Sanity client export const config = { api: { bodyParser: false, }, }; export default async function handler( req: NextApiRequest, res: NextApiResponse ) { try { const data = await new Promise((resolve, reject) => { const form = formidable(); form.parse(req, (err, fields, files) => { if (err) reject(err); else resolve({ fields, files }); }); }); const { files } = data; // 获取上传的图片文件(对应前端FormData的"file"键) const imageFile = files.file as formidable.File; if (!imageFile) { return res.status(400).json({ error: "未上传有效图片" }); } // 读取文件Buffer const imageBuffer = fs.readFileSync(imageFile.path); // 上传到Sanity const { _id } = await client.assets.upload("image", imageBuffer, { filename: imageFile.name // 保留原文件名 }); res.status(200).json(_id); } catch (err) { res.status(400).json({ error: (err as Error).message }); } }
后端代码(formidable v3版本)
v3版本默认返回文件数组,需调整文件获取方式:
import fs from 'fs'; import formidable from 'formidable'; // 导入你的Sanity client export const config = { api: { bodyParser: false, }, }; export default async function handler( req: NextApiRequest, res: NextApiResponse ) { try { // 单文件上传可关闭multiples const form = formidable({ multiples: false }); // v3使用异步解析方式 const [fields, files] = await form.parse(req); // 获取第一个上传的图片文件 const imageFile = files.file?.[0]; if (!imageFile) { return res.status(400).json({ error: "未上传有效图片" }); } // 读取文件Buffer const imageBuffer = fs.readFileSync(imageFile.filepath); // 上传到Sanity const { _id } = await client.assets.upload("image", imageBuffer, { filename: imageFile.originalFilename // 保留原文件名 }); res.status(200).json(_id); } catch (err) { res.status(400).json({ error: (err as Error).message }); } }
内容的提问来源于stack exchange,提问作者Amit Kumar
相关产品推荐
相关产品推荐

