反应发送对象数组作为表单数据

React sending array of objects as form Data

我目前创建了一个 nodejs api,用户可以在其中发送有关其职业的数据。他们可以发送文本和上传的图片。

数据发送如下,我用postman发送成功

{
    "employee": "user",
    "positionHeld": [{
        "yearPostitionHeld": "1995 - 2000",
        "positionHeldTitle": "Manager"
    },
    {
        "yearPostitionHeld": "2000 - Present",
        "positionHeldTitle": "Assocaite Manager"
    }],
    "address": "Company Address",
    "responsibilities": ["Responsibility 1", "Responsibility 2", "Responsibility 3"]
}

我用 ReactJS 创建了一个前端页面,这样用户就可以通过填写输入字段来发送上述数据。

我通过 useState Hook 设置用户输入

const [formData, setFormData] = useState({
    companyName: "",
    year: "",
    positionHeld: [
      {
        positionHeldYear: "",
        positionHeldTitle: "",
      },
    ],
    address: "",
    responsibilities: "",
  });

通过 onChange 函数

const onChange = (e) => {
    setFormData({ ...formData, [e.target.name]: e.target.value });
  };

我也搞定了文件上传

const [fileData, setFileData] = useState();

const handleFilechange = (e) => {
    setFileData(e.target.files[0]);
  };

我首先尝试将数据作为 formData 发送,但是 file/image 总是出现在 req.body 而不是 req.file 中,因此我无法获取文件路径。

作为文件问题的解决方案,我创建了一个新的 formData const completeFormData = new FormData(); 并附加了这个

const year = formData.positionHeldYear;
    const title = formData.positionHeldTitle;
    setFormData({...formData, positionHeld: {positionHeldYear: year, positionHeldTitle: title}})

completeFormData.append("companyName", formData.companyName);
    completeFormData.append("year", formData.year);
    completeFormData.append("positionHeld", formData.positionHeld); // this needs to send the array of objects
    completeFormData.append("address", formData.address);
    completeFormData.append("responsibilities", formData.responsibilities);
    completeFormData.append("image", fileData);

我不确定是否可以将对象数组作为新的 FormData 发送,例如

"positionHeld": [{
        "yearPostitionHeld": "1995 - 2000",
        "positionHeldTitle": "Manager"
    },
    {
        "yearPostitionHeld": "2000 - Present",
        "positionHeldTitle": "Assocaite Manager"
    }],

当 req.body 进入后端时,如上所述创建新表单数据时,positionHeld 在执行控制台日志时显示为 positionHeld: [object, Object]

如何最好地管理使用嵌套对象字符串数组和图像上传发送数据?

我可能走错了路,所以希望有人能指出正确的方向来发送正文和文件以确认我的对象

{
    "employee": "user",
    "positionHeld": [{
        "yearPostitionHeld": "1995 - 2000",
        "positionHeldTitle": "Manager"
    },
    {
        "yearPostitionHeld": "2000 - Present",
        "positionHeldTitle": "Assocaite Manager"
    }],
    "address": "Company Address",
    "responsibilities": ["Responsibility 1", "Responsibility 2", "Responsibility 3"]
}

在 FormData 中发送数组的一种方法是序列化它:

completeFormData.append("positionHeld", JSON.stringify(formData.positionHeld));

然后,在后端,你可以用JSON.parse()解析它。

我们是用 ReactJS(front) 和 ASP.Net core(back) 做的所以最好的方法是使用 FormData,我们使用一个像下面这样的对象,它包含一个对象数组,每个对象包括还有一组图片,

{
    CommodityID:xxxxx,
    TotalWeight:xxxx,
    CostOfCommodity:xxxx,
    Prerequisites:[{
        ProductId: xxxx,
        DeliveryWeight: xxxxx,
        ReleasedImagesUrl: [
            multiple images file
        ]
    },{
        ProductId: xxxx,
        DeliveryWeight: xxxxx,
        ReleasedImagesUrl: [
            multiple images file
        ]
    }]
}

实际上,我们像Prerequisites[0].DeliveryWeight一样分别发送数组的每一项,这就是重点(成对的name/value)。请注意在我们的例子中项目的第一个字符是大写的字母(这也很重要)

const formData = new FormData();
    formData.append("CommodityID", this.state.commodityId);
    formData.append("TotalWeight", this.state.totalWeight);
    formData.append("CostOfCommodity",this.state.costOfCommodity);
    for (let i = 0; i < this.state.prerequisitesListTemp.length; i++) {
      formData.append(
        `Prerequisites[${i}].ProductId`,
        this.state.prerequisitesListTemp[i].productId
      );
      formData.append(
        `Prerequisites[${i}].DeliveryWeight`,
        this.state.prerequisitesListTemp[i].deliveryWeight
      );

      for (
        let j = 0;j < this.state.prerequisitesListTemp[i].releasedImagesUrl.length;j++
      ) {
        formData.append(
          `Prerequisites[${i}].ReleasedImagesUrl`,
          this.state.prerequisitesListTemp[i].releasedImagesUrl[j]
        );
      }
    }