9/9 `req.json()`이 동작하지 않는 이슈 해결

낄낄박사·2024년 9월 9일

Gotcha

목록 보기
19/22

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와 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 헤더를 수동으로 설정해야 한다는 걸 알게됨.

다음에도 비슷한 상황이 발생하면 헤더 설정부터 확인해봐야겠음

0개의 댓글