POST请求提交数据遇400错误,字段校验失败求助排查
问题:React表单向数据库提交POST请求时返回400(Bad Request)
后端返回提示:{message: 'Please fullfil all fields!'}。已确认表单输入项名称、类型与后端Schema均为字符串类型,且能正确获取输入值,但数据始终无法提交。相关代码如下:
CreateRecipe组件代码
import "./CreateRecipe.css"; import { Link, NavLink, useNavigate } from 'react-router-dom'; import React, { useLayoutEffect, useState } from 'react'; import * as recipeService from "../../../services/recipeService"; const CreateRecipe = () => { useLayoutEffect(() => { window.scrollTo(0, 0) }); const scrollToTop = () => { window.scrollTo(0, 0) } const navigate = useNavigate(); const onCreateRecipe = (e) => { e.preventDefault(); let recipeData = new FormData(e.currentTarget); let name = recipeData.get('name'); let time = recipeData.get('time'); let imageUrl = recipeData.get('imageUrl'); let ingredients = recipeData.get('ingredients'); let instructions = recipeData.get('instructions'); recipeService.create({ name, time, imageUrl, ingredients, instructions, }) .then(result => { navigate('/recipes'); }) } return ( <div className = "maind"> <section className="sec3"> <div> <h1>Add Your Recipe</h1> <form id="createform" onSubmit={onCreateRecipe} method="POST"> <fieldset> <legend>Fill the form</legend> <label name="namel">Name</label> <input type="text" name = "name" id="name" placeholder="...."/> <label name="timel">Time</label> <input type="text" name = "time" id="time" placeholder="...."/> <label name="url">Url</label> <input type="text" name = "imageUrl" id="imageUrl" placeholder="...."/> <label name="ingredl">Ingredients</label> <textarea name = "ingredients" id="ingredients" placeholder="...."/> <label name="instl">Instructions</label> <textarea name = "instructions" id="instructions" placeholder="...."/> <button class="btnad" type="submit">Add</button> </fieldset> </form> </div> </section> <section className="sec5navl"> <ul> <li><Link smooth= "true" to="/"><i className="fas fa-solid fa-book-bookmark"></i></Link>Home</li> <li><Link smooth= "true" to="/recipes"><i className="fas fa-thin fa-bowl-rice"></i></Link>Recipes</li> <li><Link smooth= "true" to="/personal-list"><i className="fas fa-solid fa-list-ul"></i></Link>Your Recipes</li> <li><Link smooth= "true" to="/favourites"><i className="fa-solid fa-heart"></i></Link>Favourites</li> <li><Link smooth= "true" to="/create-recipe"><i className="fas fa-solid fa-plus"></i></Link>Add Recipe</li> <li><Link smooth= "true" to="/user-profile"><i className="fas fa-solid fa-user"></i></Link>Your Profile</li> <li><Link smooth= "true" onClick={scrollToTop} to="/create-recipe"><i class="fas fa-solid fa-arrow-up"></i></Link>Up</li> </ul> </section> </div> ); } export default CreateRecipe;
recipeService中的create函数代码
export const create = (recipeData) => { let response = fetch(`${baseUrl}/recipes`, { method: 'POST', headers: { 'content-type': 'application-json', }, body: JSON.stringify(recipeData) }); let result = response.json(); return result; };
解决方法
1. 修复请求头的Content-Type拼写错误
create函数里的content-type值存在拼写错误,正确的JSON类型请求头应为application/json:
headers: { 'content-type': 'application/json', // 修正此处的拼写错误 },
2. 处理fetch的异步特性
fetch返回的是Promise对象,无法直接调用.json(),需通过async/await或.then()链式调用处理异步逻辑:
// 用async/await改写create函数 export const create = async (recipeData) => { let response = await fetch(`${baseUrl}/recipes`, { method: 'POST', headers: { 'content-type': 'application/json', }, body: JSON.stringify(recipeData) }); let result = await response.json(); return result; }; // 或用.then()链式调用实现 export const create = (recipeData) => { return fetch(`${baseUrl}/recipes`, { method: 'POST', headers: { 'content-type': 'application/json', }, body: JSON.stringify(recipeData) }) .then(response => response.json()); };
3. 前端增加表单空值验证
在提交前验证字段是否为空字符串,避免无效请求:
const onCreateRecipe = (e) => { e.preventDefault(); let recipeData = new FormData(e.currentTarget); // 去除字段首尾空格并验证 let name = recipeData.get('name').trim(); let time = recipeData.get('time').trim(); let imageUrl = recipeData.get('imageUrl').trim(); let ingredients = recipeData.get('ingredients').trim(); let instructions = recipeData.get('instructions').trim(); if (!name || !time || !imageUrl || !ingredients || !instructions) { alert('请填写所有必填字段'); return; } recipeService.create({ name, time, imageUrl, ingredients, instructions, }) .then(result => { navigate('/recipes'); }) .catch(err => { console.error('提交失败:', err); // 捕获错误便于排查问题 }) }
内容的提问来源于stack exchange,提问作者DimitriTfb
相关产品推荐
相关产品推荐

