#7 Route Handler는 매번 익숙해지지 않네

김병훈·2024년 3월 30일
0

bora-n-maria

목록 보기
7/7
post-thumbnail

겪은 문제

1. file을 보내려면?

문제

fetch를 통해 Route Handler로 요청을 보낼 때, data에 파일을 그대로 넣었더니 json() 메서드로 파싱시, 에러가 발생했다.

// StoryForm.tsx
const uploadImageFile = async (file: File) => {
  const res = await fetch(url, {
    method: 'POST',
    body: compressedImageFile,
  });
  
  //...
}
// route.ts
export const POST = async (req) => {
  const requestBody = await req.json();
  // SyntaxError: Unexpected token R in JSON at position 0
}

문제 원인

파일을 API Route로 보내고 처리하는 과정에서 JSON으로 데이터를 파싱하려고 시도했을 때 발생하는 문제는 파일 데이터를 JSON 형식으로 직접 보내려고 했기 때문이다.
파일은 바이너리 데이터이므로 JSON 형식으로 직접 변환되지 않는다. 따라서 파일을 전송할 때는 FormData 객체를 사용하여 멀티파트 형식으로 데이터를 인코딩해야 한다.

문제 해결

// StoryForm.tsx
const uploadImageFile = async (file: File) => {
  const formData = new FormData();
  formData.append('file', file);
  
  const res = await fetch(url, {
    method: 'POST',
    body: formData,
  });
  
  //...
}
// route.ts
export const POST = async (req) => {
  const requestBody = await req.formData();
  // ...
}

2. File 타입을 확인할 수 없다?

문제

Route Handler에서 요청 formData에 있는 내용이 File 타입인지 확인하기 위해, instanceof를 통해 체크하려고 했다.
하.지.만
에러가 발생했다.

const checkIsFile = (value: unknown): value is File => {
  return value instanceof File;
}
// ReferenceError: File is not defined

문제 원인

File 객체가 서버 측(Node.js) 환경에서 정의되어 있지 않기 때문이다. File 객체는 브라우저의 Web API의 일부로, 브라우저 환경에서만 사용할 수 있다. 따라서, Next.js의 서버 측 로직(ex: API Route Handler)에서는 접근할 수 없다.

문제 우회

formData에 담긴 file 객체의 타입을 체크하진 않고, 존재하는지만 확인하도록 함.

export const POST = async (req: NextRequest) => {
  const formData = await req.formData();
  const file = formData.get('file');
  
  if (!file) {
    return NextResponse.json({ message: "BadRequest" }, { status: 400 });
  }
  
  // ...
}
profile
재밌는 걸 만드는 것을 좋아하는 메이커

0개의 댓글