Next.js调用mockapi.io POST接口遇400错误及Server Actions使用疑问
一、解决MockAPI 400 Bad Request错误
以下是排查和解决方向:
查看具体错误响应:当前代码仅打印响应对象,无法获取MockAPI返回的具体错误原因。修改
try块,添加响应内容读取逻辑:const res = await fetch("https://65ae7ed21dfbae409a74f76c.mockapi.io/api/v1/board", { method: "POST", body: JSON.stringify(submitData), headers: { "content-type": "application/json", }, }); // 新增:读取错误详情 const errorDetails = await res.text(); console.log("错误详情:", errorDetails);MockAPI通常会返回明确提示,比如字段缺失、格式不匹配等。
校验请求数据与配置匹配度:从你的配置截图来看,
board资源字段为title(小写),代码提交的{ title: boardTitle }格式正确,但需确保:- 提交的
boardTitle不是空字符串或仅空格(可在提交前添加校验:if (!boardTitle.trim()) return;) - MockAPI后台未设置其他必填字段(截图仅显示
title,建议确认资源配置)
- 提交的
验证接口URL正确性:直接在浏览器访问
https://65ae7ed21dfbae409a74f76c.mockapi.io/api/v1/board,若返回空数组或已有看板数据,说明URL正确;若返回404,需检查资源名称或URL拼写。检查请求头:当前设置的
content-type: application/json符合MockAPI要求,无需额外请求头(除非后台配置了API密钥,需补充Authorization头)
二、Next.js结合MockAPI的两种实现方案
并非只能用API路由,Server Actions也可直接使用,具体如下:
方案1:使用Server Actions
Server Actions是Next.js 13+ App Router特性,可在组件中直接定义服务器端运行的函数,无需单独创建API路由:
// app/(platform)/(dashboard)/organization/[organizationId]/page.tsx import { useState } from "react"; // 标记为Server Action const createBoard = async (boardTitle: string) => { "use server"; const submitData = { title: boardTitle.trim() }; try { const res = await fetch("https://65ae7ed21dfbae409a74f76c.mockapi.io/api/v1/board", { method: "POST", body: JSON.stringify(submitData), headers: { "content-type": "application/json", }, }); if (!res.ok) { const errorDetails = await res.text(); throw new Error(`创建看板失败: ${errorDetails}`); } return await res.json(); } catch (error) { console.error(error); throw error; } }; const OrganizationIdPage = () => { const [boardTitle, setBoardTitle] = useState(""); const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); if (!boardTitle.trim()) return; try { await createBoard(boardTitle); console.log("看板创建成功"); setBoardTitle(""); } catch (error) { console.error(error); } }; return ( <div> <form onSubmit={handleSubmit}> <input type="text" id="title" name="title" required placeholder="输入看板标题" className="border-input border p-1" value={boardTitle} onChange={(e) => setBoardTitle(e.target.value)} /> <button type="submit" className="btn-primary"> 创建看板 </button> </form> </div> ); }; export default OrganizationIdPage;
方案2:使用API路由
若习惯传统API路由模式,可创建如下路由文件:
// app/api/boards/route.ts import { NextResponse } from "next/server"; export async function POST(request: Request) { const { title } = await request.json(); if (!title.trim()) { return NextResponse.json({ error: "标题不能为空" }, { status: 400 }); } try { const res = await fetch("https://65ae7ed21dfbae409a74f76c.mockapi.io/api/v1/board", { method: "POST", body: JSON.stringify({ title: title.trim() }), headers: { "content-type": "application/json", }, }); const data = await res.json(); return NextResponse.json(data, { status: res.status }); } catch (error) { return NextResponse.json({ error: "创建看板失败" }, { status: 500 }); } }
然后在客户端组件中调用该API路由:
// app/(platform)/(dashboard)/organization/[organizationId]/page.tsx "use client"; import { useState } from "react"; const OrganizationIdPage = () => { const [boardTitle, setBoardTitle] = useState(""); const createBoard = async (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); if (!boardTitle.trim()) return; try { const res = await fetch("/api/boards", { method: "POST", body: JSON.stringify({ title: boardTitle }), headers: { "content-type": "application/json", }, }); if (res.ok) { console.log("看板创建成功"); setBoardTitle(""); } else { const error = await res.json(); throw new Error(error.error); } } catch (error) { console.log(error); } }; return ( <div> <form onSubmit={createBoard}> <input type="text" id="title" name="title" required placeholder="输入看板标题" className="border-input border p-1" onChange={(e) => setBoardTitle(e.target.value)} value={boardTitle} /> <button type="submit" className="btn-primary"> 创建看板 </button> </form> </div> ); }; export default OrganizationIdPage;
内容的提问来源于stack exchange,提问作者Ole Me
相关产品推荐
相关产品推荐

