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

使用FormData.append()传文件至后端,Firefox/Safari报参数非对象错误

跨浏览器FormData上传问题排查与解决

看起来你遇到的是Chrome与Firefox/Safari在FormData参数处理上的兼容性差异——Chrome对非标准参数有容错机制,但Firefox和Safari严格遵循W3C规范,所以会抛出Argument 2 of FormData.append is not an object错误。

问题根源

FormData的append()方法标准要求第二个参数只能是以下类型之一:

  • USVString(字符串)
  • Blob(包括子类File)

Chrome会自动将非上述类型的参数(比如普通JavaScript对象)转换为字符串(比如[object Object]),但Firefox和Safari会直接校验参数类型,发现是不允许的对象时就抛出错误。

从你的代码片段看,问题出在childData.forEach((data: any) => ...)这部分——你大概率是直接把childData里的整个对象(包含文件和文档详情)传给了formData.append(),而不是拆解成合法的参数类型。

解决方案

根据你的业务需求,有两种常见的修复方式:

1. 拆分字段单独上传(推荐,适用于包含File的场景)

如果childData的每个项是包含File和其他文档字段的对象,需要把File和普通字段分别append到FormData:

childData.forEach((item: any, index: number) => {
  // 上传文件:确保item.file是File/Blob类型
  if (item.file && item.file instanceof File) {
    formData.append(`childFiles[${index}]`, item.file, item.file.name);
  }

  // 上传文档详情:逐个append字符串类型的字段
  formData.append(`childDocs[${index}][title]`, item.title || '');
  formData.append(`childDocs[${index}][description]`, item.description || '');
  // 其他字段依此类推...
});

2. 将非文件数据序列化为JSON上传

如果你的文档详情是复杂嵌套对象,不想逐个拆解,可以把非File部分转成JSON字符串再上传,后端再解析:

childData.forEach((item: any, index: number) => {
  // 单独上传File
  if (item.file && item.file instanceof File) {
    formData.append(`childFiles[${index}]`, item.file, item.file.name);
  }

  // 把非File的文档详情转成JSON字符串
  const docDetails = { ...item };
  delete docDetails.file; // 移除File字段,因为无法被JSON序列化
  formData.append(`childDocs[${index}]`, JSON.stringify(docDetails));
});

额外注意事项

  • 确保所有传给append()的第二个参数都是合法类型:避免直接传入undefined、null或者普通对象。
  • 如果childData里有数组类型的字段,同样需要拆解或者转成字符串后再上传。
  • 可以在append前加类型校验,提前规避错误:
    const isValidFormValue = (val: any) => {
      return typeof val === 'string' || val instanceof Blob;
    };
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:40:08