개요
어느 날, 파일 업로드에 오류가 발생했다.
프론트에서 이미지 업로드에 성공했으나, 업로드한 경로에 이미지가 없다고 404 에러가 발생했다.
현재 프로젝트에서는 이미지는 CDN에 업로드하고, 파일 경로를 백엔드에 문자열로 저장한다.
이미지 업로드, 데이터 저장 모두 성공적으로 요청되었기에 원인을 파악하려 하나씩 살펴보았다.
[문제가 발생한 환경]
Nest 9.1.4
Multer 1.4.4-lts.1
busboy 1.6.0
원인 확인
Middleware로 NestJS를 사용하고 있었는데, 파일명에 한글이 포함된 경우만 NestJS로 넘어온 파일명이 이상하게 변환된 걸 확인했다.
CDN에 파일을 요청할 때, 요청한 파일명과 백엔드에 저장한 파일명이 달라 404가 내려온 것으로 판단하였다.
해결을 위한 과정
- NestJS에서 파일명이 깨지는 이슈를 검색해보았지만 찾을 수 없었다
- NestJS에선 파일 업로드를 처리하기 위해 Multer의 내장 메서드인
FilesInterceptor
를 사용한다 - 해당 interceptor에 문제가 있을 것으로 유추했고, 깃허브에 등록된 이슈를 확인할 수 있었다
결론
- Multer의 종속성으로 사용되는 busboy는 파라미터 디코딩에 'latin1' 문자셋을 사용한다
- 한글 같은 비-라틴 문자가 포함된 파일명을 처리할 때 잘못 디코딩되고 있었다
- Multer 내에서 busboy의 설정 속성을 직접 변경할 수 있는 옵션이 현재 없다
해결
파일명을 강제로 인코딩하는 코드를 추가하여 해결했다.
const fileName = Buffer.from(file.originalname, 'latin1').toString('utf8');
Buffer.from(el.originalname, 'latin1')
는 파일명을 'latin1' 인코딩으로 버퍼 객체로 변환합니다.
.toString('utf8')
는 이 버퍼 객체를 'utf8' 문자열로 변환합니다.
버퍼 객체란? Node.js에서 이진 데이터를 효율적으로 처리하기 위해 사용되는 객체
'TECH' 카테고리의 다른 글
Angular ngIf 처럼 동작하는 custom directive 만들기 (0) | 2024.05.01 |
---|---|
PM2, NGINX 자동 실행하기 (0) | 2024.01.14 |