express에서 multer를 이용해서 사용자의 프로필 사진 변경 api를 구현하고 있었는데,
분명 클라이언트에서는 사진 파일을 정상적으로 받아서 보내는데, 서버에서 계속 undefined로 받는 상황이 생겼다.
처음엔 변수명 타입이 잘못되어있었다 (...) 그래서 profileImage -> profileImg 로 일괄 수정했지만 변화가 없었다.
이것저것 세세하게 디버깅 해봤는데 원인을 찾지 못해서 골머리를 앓았다... :)
그러다 결국 원인을 찾아서 해결했고...범인은 프론...트...
이게 문제가 됐던 코드이다. formData를 보내주면서 headers를 Content-Type: multipart/form-data로 설정해주지 않았는데, 그 이유는 브라우저가 formData에 맞는 헤더와 boundary를 자동으로 설정해주기 때문이었다.
오히려 설정하면...파일이 아니라 문자열이 들어왔을 땐 오류가 나지 않았을까 싶다.
그래서 비워두었던건데, 혹시몰라서 headers를 Content-Type: multipart/form-data로 설정해주니까 바로 해결됐다.
좀 의아해서... multipart/form-data가 아닌 null로 설정해보았더니 이것도 가능했다.
알고보니 Content-Type 충돌문제였다. 내가 axios 인스턴스를 생성할 때 아래와 같이 application/json으로 기본값을 지정해놓았기 때문이다.
그래서 formData에 맞게 자동으로 할당되지 않고 application/json으로 요청이 전송되다보니까 오류가 났던 것이다.
그래서 파일 업로드하는 함수에서는 axios 인스턴스를 호출할 때 이렇게 null로 설정해줘야된다는 것을 알았다.
이렇게하면 axios가 기본 application/json 헤더를 설정하지 않게 되어 자동으로 할당된다.
그런데 이 방법보다 더 근본적인 해결 방안은 아래와 같이 axios 인스턴스를 수정하는 것이다.
원래 기본값이었던 헤더를 지우고,
data에 FormData가 들어오면 Content-Type 헤더를 지우고, 나머지는 application/json 헤더를 설정해주는 방법이다.
프로필 사진을 받아서 수정하는 api가 간단할 줄 알았는데 쉽지 않은 작업인 것 같다... 파일을 마냥 로컬에 쌓을 수도 없고 클라우드 서비스를 이용해야해서 🤔......쉽지 않다...
'트러블 슈팅' 카테고리의 다른 글
[Next.js + Zustand] localStorage hydration 에러 핸들링 (0) | 2025.05.02 |
---|---|
[Node.js] prisma 클라이언트 초기화 오류 해결하기 (1) | 2025.04.16 |
[Next.js] Image 경고(LCP, 종횡비) 해결하기 (0) | 2025.04.10 |
[React/Zustand] 리액트 훅은 함수 컴포넌트 내부에서만 호출될 수 있습니다. (0) | 2025.03.02 |