Next.js API 라우트에서 req.json()이 정상적으로 동작하지 않는 문제를 겪음
Next.js API 라우트에서 클라이언트로부터 JSON 데이터를 받아 처리하려고 했으나, req.json()이 제대로 동작하지 않고 다음과 같은 에러가 발생함
SyntaxError: Unexpected end of JSON input
문제의 코드
import { addProduct } from "@/services/product";
import { NextRequest, NextResponse } from "next/server";
export async function POST(req: NextRequest, res: NextResponse) {
if (req.method !== "POST") {
return new Response("Method Not Allowed", { status: 405 });
}
const newProduct = await req.json(); // 이 부분에서 에러 발생
if (!newProduct) {
return new Response("Bad Request", { status: 400 });
}
return addProduct(newProduct)
.then((res) => NextResponse.json(res))
.catch((error) => error.message);
}
API 라우트에서 req.json()으로 요청 본문을 파싱하는 부분에서 문제가 발생하고 있었음
문제의 원인은 클라이언트에서 요청을 보낼 때 Content-Type 헤더를 명시하지 않았기 때문이었다.. 클라이언트가 서버에 JSON 데이터를 전송할 때, Content-Type: application/json 헤더가 설정되지 않으면, 서버는 JSON 형식의 데이터를 받는 것으로 인식하지 못하고, req.json()이 실패함.
이전에 FormData를 사용할 때는 문제가 없었던 이유는, 브라우저가 자동으로 Content-Type: multipart/form-data 헤더를 설정해주기 때문임. 반면, JSON 데이터를 전송할 때는 수동으로 Content-Type을 설정해야 한다.
해결 방법은 클라이언트에서 요청을 보낼 때 Content-Type: application/json 헤더를 명시해줌. 클라이언트의 코드에서 다음과 같이 수정
const res = await fetch("/api/products", {
method: "POST",
headers: {
"Content-Type": "application/json", // 헤더 추가
},
body: JSON.stringify(newProduct),
});
헤더를 추가한 후, 서버에서 req.json()을 사용하여 데이터를 정상적으로 파싱할 수 있었다.
import { addProduct } from "@/services/product";
import { NextRequest, NextResponse } from "next/server";
export async function POST(req: NextRequest, res: NextResponse) {
if (req.method !== "POST") {
return new Response("Method Not Allowed", { status: 405 });
}
const newProduct = await req.json();
if (!newProduct) {
return new Response("Bad Request", { status: 400 });
}
return addProduct(newProduct)
.then((res) => NextResponse.json(res))
.catch((error) => error.message);
}
FormData는 브라우저가 자동으로 적절한 Content-Type 헤더를 설정해주지만, JSON 데이터를 전송할 때는 반드시 Content-Type: application/json 헤더를 수동으로 설정해야 한다는 걸 알게됨.다음에도 비슷한 상황이 발생하면 헤더 설정부터 확인해봐야겠음