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

将获取的数据传入POST表单时遇400错误,如何解决?

问题分析与解决方案

核心问题

后端控制器依赖multer处理文件上传(multipart/form-data格式),但前端发送的是JSON格式的图片URL数组,没有实际上传文件,导致multer触发No files uploaded的校验错误,返回400状态码。


方案一:复用已有图片URL(无需上传新文件)

如果需求是直接使用从其他API获取的图片URL,不需要上传新文件,修改后端代码移除文件上传逻辑即可:

// backend/controllers/hire.js
const Vehicle = require("../models/Hire");
const { StatusCodes } = require("http-status-codes");
const { BadRequestError } = require("../errors");

const AddHire = async (req, res) => {
  console.log("backend", req.body);

  // 校验必要字段(根据数据模型调整)
  const requiredFields = ['name', 'pictures', 'description', 'colour', 'transmission', 'type', 'seat', 'price'];
  const missingFields = requiredFields.filter(field => !req.body[field]);
  
  if (missingFields.length > 0) {
    return res.status(StatusCodes.BAD_REQUEST)
      .json({ error: `缺少必要字段:${missingFields.join(', ')}` });
  }

  // 注入创建者ID
  req.body.createdBy = req.user.userId;

  // 直接使用前端传入的图片URL数组,无需Cloudinary上传
  const { note, ...vehicleDetails } = req.body;
  const vehicleWithNote = { ...vehicleDetails, note };

  const vehicle = await Vehicle.create(vehicleWithNote);

  res.status(StatusCodes.CREATED).json({ vehicle });
};

module.exports = {
  AddHire,
};

方案二:上传新图片文件(适配后端multer逻辑)

如果需要用户上传新图片,前端需要改用FormData发送请求,匹配后端的文件上传逻辑:

前端Form组件修改

"use client";

import { useState } from "react";
import sendFormWithVehicleDetails from "@/lib/postHire";

export default function Form({ vehicle }: { vehicle: Vehicle }) {
  const { name, seat, price, description, type, colour, transmission } = vehicle;
  const [note, setNote] = useState("");
  const [pictures, setPictures] = useState<File[]>([]);

  async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();

    const formData = new FormData();
    // 添加文本字段
    formData.append('name', name);
    formData.append('seat', seat.toString());
    formData.append('price', price.toString());
    formData.append('description', description);
    formData.append('type', type);
    formData.append('colour', colour);
    formData.append('transmission', transmission);
    formData.append('note', note);
    // 添加图片文件
    pictures.forEach(file => formData.append('pictures', file));

    try {
      await sendFormWithVehicleDetails(formData);
      console.log("表单提交成功");
    } catch (error) {
      console.error("提交失败:", error);
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <div className="mb-3">
        <label htmlFor="examplenote1" className="form-label">
          添加备注
        </label>
        <input
          type="text"
          className="form-control"
          id="exampleInputEmail1"
          aria-describedby="textHelp"
          placeholder="例如:记得带雨伞"
          value={note}
          onChange={(e) => setNote(e.target.value)}
        />
      </div>
      <div className="mb-3">
        <label className="form-label">上传图片(最多5张)</label>
        <input
          type="file"
          className="form-control"
          multiple
          accept="image/jpeg,image/png,image/svg+xml"
          onChange={(e) => {
            if (e.target.files) setPictures(Array.from(e.target.files));
          }}
        />
      </div>

      <button type="submit" className="btn btn-primary">提交</button>
    </form>
  );
}

请求函数修改

import Cookies from "js-cookie";

export default async function sendFormWithVehicleDetails(formData: FormData) {
  const url = "http://127.0.0.1:3000/api/v1/hire";
  const token = Cookies.get("token");

  const response = await fetch(url, {
    method: "POST",
    headers: {
      authorization: `Bearer ${token}`,
      // 不要手动设置Content-Type,浏览器会自动添加正确的multipart/form-data边界
    },
    body: formData,
  });

  if (!response.ok) {
    const errorResponse = await response.json();
    throw new Error(`请求失败,状态码${response.status}:${JSON.stringify(errorResponse)}`);
  }

  return await response.json();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 03:38:12