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

FormData提交表单时medication_files字段缺失的技术求助

FormData提交表单时medication_files字段缺失的技术求助

大家好,我最近在做React表单提交功能时遇到了棘手的问题:用FormData向Rails后端提交数据时,patient_name、age等普通字段都能正常发送,但medication_files文件数组始终无法被正确附加到FormData中,后端完全接收不到这部分内容。我加了一堆调试日志还是没找到根源,麻烦各位有经验的大佬帮忙排查一下!

问题核心细节

  • 用Formik管理表单状态,medicationFiles是File[]类型,通过文件选择框的onChange事件,用setFieldValue更新Formik状态
  • 提交时手动创建FormData,逐个附加字段,文件部分通过循环forEach调用append方法
  • 控制台打印values.medicationFiles能看到选中的文件对象,但FormData里完全没有这部分条目

前端完整代码(React + Formik + TypeScript + Axios)

import { Formik, Field, Form, ErrorMessage } from 'formik';
import './PrescriptionForm.scss';
import { prescriptionSchema } from '../../utils/schema';
import axios from 'axios';
import { getCookie } from '../../utils/helper/tokenHandler';

const PrescriptionForm = () => {
  console.log("Debugging!!!");

  const handleSubmit = async (
    values: {
      patientName: string;
      age: number;
      gender: string;
      date: string;
      medicationFiles: File[];
    },
    { setSubmitting, resetForm }: {
      setSubmitting: (isSubmitting: boolean) => void;
      resetForm: () => void
    }
  ) => {
    const token = getCookie();
    const formData = new FormData();

    formData.append('prescription[patient_name]', values.patientName);
    formData.append('prescription[age]', values.age.toString());
    formData.append('prescription[gender]', values.gender);
    formData.append('prescription[date]', values.date);

    console.log('Type:', typeof values.medicationFiles);
    if (values.medicationFiles && values.medicationFiles.length > 0) {
      values.medicationFiles.forEach((file) => {
        formData.append('prescription[medication_files][]', file);
      });
    }

    console.log('Files appended to FormData:');
    Array.from(formData.entries()).forEach(([key, value]) => {
      console.log(`${key}:`, value);
    });
    console.log('medicationFiles:', values.medicationFiles);

    try {
      console.log("Submitting prescription with values:", values);
      console.log("Form data:", formData);
      const res = await axios.post(
        'http://localhost:3000/api/v1/prescriptions',
        formData,
        {
          headers: {
            Authorization: `Bearer ${token}`,
            // 注意:这里可能需要显式设置Content-Type为multipart/form-data,但Axios会自动处理
            // 'Content-Type': 'multipart/form-data'
          },
        }
      );
      console.log(res);
      alert('Prescription submitted successfully!');
      resetForm();
    } catch (error) {
      console.error('Submit error:', error);
      if (
        typeof error === 'object' && error !== null && 'response' in error &&
        (error as any).response?.data?.errors
      ) {
        alert('Submission failed: ' + (error as any).response.data.errors.join(', '));
      } else {
        alert('An unexpected error occurred. Please try again.');
      }
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <Formik
      initialValues={{
        patientName: '',
        age: 0,
        gender: '',
        date: '',
        medicationFiles: [],
      }}
      validationSchema={prescriptionSchema}
      onSubmit={handleSubmit}
    >
      {({ values, isSubmitting, setFieldValue }) => (
        <Form className="prescription-form">
          <h2>Prescription Form</h2>
          <label>Patient Name</label>
          <Field name="patientName" />
          <ErrorMessage name="patientName" component="div" />

          <label>Age</label>
          <Field
            name="age"
            type="number"
            parse={(value: string) => (value === '' ? 0 : Number(value))}
          />
          <ErrorMessage name="age" component="div" />

          <label>Gender</label>
          <Field name="gender" as="select">
            <option value="">Select</option>
            <option value="male">Male</option>
            <option value="female">Female</option>
            <option value="other">Other</option>
          </Field>
          <ErrorMessage name="gender" component="div" />

          <label>Date</label>
          <Field name="date" type="date" />
          <ErrorMessage name="date" component="div" />

          <label>Medication File</label>
          <input
            name="medicationFiles"
            type="file"
            accept=".pdf,.doc,.docx"
            multiple
            onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
              const files = Array.from(e.currentTarget.files || []);
              setFieldValue("medicationFiles", files);
            }}
          />
          <ErrorMessage name="medicationFiles" component="div" />

          <button type="submit" disabled={isSubmitting}>Submit</button>
        </Form>
      )}
    </Formik>
  );
};

export default PrescriptionForm;

后端情况(Rails)

目前Rails后端日志中,完全接收不到medication_files相关参数,其他表单字段(如patient_name、age等)都能被正常解析并写入数据库。

调试中观察到的关键现象

  1. 打印typeof values.medicationFiles结果为object,且values.medicationFiles.length确实大于0
  2. 遍历values.medicationFiles时,控制台能输出正常的File对象
  3. 执行formData.append后,用Array.from(formData.entries())打印所有条目,完全看不到prescription[medication_files][]相关内容

麻烦各位帮忙看看哪里出问题了,谢谢!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 11:14:52