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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 11:37:42