Next.js组件发送DELETE请求遇405错误,POST请求正常求助
问题分析与解决方案
你遇到的DELETE请求返回405 Method Not Allowed错误,大概率是以下原因之一:
1. Next.js路由模式不匹配(最可能)
如果你的项目使用App Router(Next.js 13+,目录结构为app/),但API路由仍用Pages Router的写法(单个handler函数),会导致非POST请求被拒绝。App Router要求API路由必须单独导出对应HTTP方法的函数。
修复方案:
将like.ts(假设路径为app/api/like/route.ts)改为App Router兼容写法:
import { fetchThreadById } from "@/lib/actions/thread.actions"; import Like from "@/lib/models/like.model"; import { connectToDB } from "@/lib/mongoose"; import { NextResponse } from "next/server"; export async function POST(request: Request) { try { const { threadId, userId } = await request.json(); if (!threadId || typeof threadId !== "string" || !userId || typeof userId !== "string") { return NextResponse.json({ error: "Invalid data" }, { status: 400 }); } await connectToDB(); const thread = await fetchThreadById(threadId); if (!thread) { return NextResponse.json({ error: "Invalid thread ID" }, { status: 400 }); } const newLike = new Like({ userId, threadId }); await newLike.save(); return NextResponse.json({ message: "Like added successfully" }, { status: 200 }); } catch (error) { console.error("Error adding like: ", error); return NextResponse.json({ error: "An error occurred" }, { status: 500 }); } } export async function DELETE(request: Request) { try { const { threadId, userId } = await request.json(); if (!threadId || typeof threadId !== "string" || !userId || typeof userId !== "string") { return NextResponse.json({ error: "Invalid data" }, { status: 400 }); } await connectToDB(); const thread = await fetchThreadById(threadId); if (!thread) { return NextResponse.json({ error: "Invalid thread ID" }, { status: 400 }); } await Like.findOneAndDelete({ userId, threadId }); return NextResponse.json({ message: "Like deleted successfully" }, { status: 200 }); } catch (error) { console.error("Error deleting like: ", error); return NextResponse.json({ error: "An error occurred" }, { status: 500 }); } }
2. DELETE请求body解析问题
部分服务器环境对DELETE请求带body的支持有限,可改为通过URL参数传递数据规避:
修复方案:
- 修改
useLike.ts中的removeLike函数:
const removeLike = async () => { try { const response = await fetch(`/api/like?threadId=${encodeURIComponent(threadId)}&userId=${encodeURIComponent(userId)}`, { method: "DELETE", }); if (response.ok) { // Handle success } else { // Handle error } } catch (error) { // Handle error } };
- 对应修改API路由(以Pages Router为例):
// 在DELETE分支中 const { threadId, userId } = req.query; if (!threadId || typeof threadId !== "string" || !userId || typeof userId !== "string") { throw new Error("Invalid parameters"); } await Like.findOneAndDelete({ userId, threadId });
3. 数据库连接时机错误
原代码中fetchThreadById在connectToDB之前调用,若该函数依赖数据库连接,会抛出错误进入catch块,可能被误判为方法不允许。
修复方案:
在try块开头先调用connectToDB:
export default async function handler(req: NextApiRequest, res: NextApiResponse) { if (req.method !== "POST" && req.method !== "DELETE") { return res.status(405).end(); } try { await connectToDB(); // 提前连接数据库 const { threadId } = req.body; // ... 后续逻辑 } catch (error) { console.log(error); return res.status(400).end(); } }
调试建议
在API路由开头添加日志,确认请求方法和参数是否正确:
console.log("Request method:", req.method); console.log("Request body:", req.body);
内容的提问来源于stack exchange,提问作者Andika Wahyu Syaputra
相关产品推荐
相关产品推荐

