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

Next.js中React Hook Form发送FormData失败及路由处理器报错排查

在Next.js中使用React Hook Form发送FormData上传文件的问题解决

你遇到的核心问题是React Hook Form默认无法正确获取file输入的File对象,导致后端拿到的不是合法的File类型,调用arrayBuffer()时报错。另外FormData.append()本身没有返回值,所以console.log(port)显示undefined是正常现象,无需关注。

解决方案步骤:

1. 修正File输入的React Hook Form绑定逻辑

React Hook Form对file input的默认处理只会返回文件名字符串,而非File对象。需要自定义onChange事件手动获取并更新表单值:

<FormField
  control={form.control}
  name="media"
  render={({ field: { onChange, name } }) => (
    <FormItem>
      <FormControl>
        <Input
          type="file"
          placeholder="media"
          onChange={(e) => {
            // 获取选中的第一个文件
            const file = e.target.files?.[0];
            if (file) {
              // 手动将File对象更新到表单
              onChange(file);
            }
          }}
          name={name}
        />
      </FormControl>
      <FormMessage />
    </FormItem>
  )}
/>

2. 修正表单类型定义

确保Inputs类型中media的类型为File | null,避免类型不匹配:

type Inputs = {
  media: File | null;
  description: string;
  // 其他表单字段...
};

3. 优化FormData组装逻辑

FormData.append()无返回值,无需赋值给变量;同时要判断文件是否存在再追加:

const onSubmit = async (data: Inputs) => {
  console.log("data", data);

  const formData = new FormData();
  // 仅当文件存在时追加到FormData
  if (data.media) {
    formData.append("media", data.media);
  }
  formData.append("description", data.description);

  try {
    setSubmitted(true);
    if (porfolio) {
      await fetch(`/api/portfolio/${porfolio.id}`, {
        method: "PATCH",
        body: formData,
      });
      setOpen(false);
      toast.success("更新成功。");
    } else {
      const port = await fetch("/api/portfolio", {
        method: "POST",
        body: formData,
      });
      console.log("port", port);
      setOpen(false);
      toast.success("作品集已创建,前往/portfolio查看变更。");
      form.reset();
      await port.json();
    }
    router.refresh();
  } catch (error) {
    setSubmitted(false);
    setError("处理过程中发生错误,请联系开发者。");
  }
};

4. 后端增加安全校验

在路由处理器中先校验拿到的是否为合法File对象,避免报错:

export async function POST(request: NextRequest) {
  const body = await request.formData();
  const file = body.get("media");
  
  // 校验是否为有效File对象
  if (!(file instanceof File)) {
    return new Response("未上传有效文件", { status: 400 });
  }
  
  console.log("file:", file);
  const arrayBuffer = await file.arrayBuffer();
  const buffer = new Uint8Array(arrayBuffer);
  // 后续业务逻辑...
}

内容的提问来源于stack exchange,提问作者Akinola

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 21:13:20