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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 20:42:24