MIME 타입만 믿고 검증했다가 브라우저에 따라 file.type이 빈 문자열로 오는 걸 겪고 나서 파일명 검사를 같이 추가했어요. media-crop 저장소의 FileUploader.tsx 얘기예요. 클릭으로 여는 파일 선택창이랑 드래그앤드롭, 두 입력 경로를 다 같은 검증 함수로 모아뒀어요.
두 입력 경로가 결국 같은 함수로 합쳐져요
const handleDrop = (e: React.DragEvent) => {
e.preventDefault();
setIsDragging(false);
const files = e.dataTransfer.files;
if (files && files.length > 0) {
validateAndSelect(files[0]);
}
};
const handleChange = (e: React.ChangeEvent) => {
const files = e.target.files;
if (files && files.length > 0) {
validateAndSelect(files[0]);
}
};
input의 accept=".mp3,.mp4,audio/*,video/*" 속성은 파일 선택창에서 확장자를 걸러주는데, 드래그앤드롭은 이 속성의 영향을 아예 안 받아요. 사용자가 아무 파일이나 끌어다 놓을 수 있으니까, 두 경로 다 결국 같은 validateAndSelect를 거치게 만들어서 입력 방식이랑 상관없이 똑같은 기준으로 검사해요.
MIME 타입만으론 부족해서 파일명도 같이 봐요
const validateAndSelect = (file: File) => {
const type = file.type.toLowerCase();
const name = file.name.toLowerCase();
const isVideo = type.includes('mp4') || type.includes('video') || name.endsWith('.mp4');
const isAudio = type.includes('mp3') || type.includes('mpeg') || type.includes('audio') || name.endsWith('.mp3');
if (isVideo || isAudio) {
onFileSelect(file);
} else {
alert("Please upload a valid MP3 or MP4 file.");
}
};
file.type은 브라우저랑 OS가 확장자나 내용 보고 추측한 값이라, 환경에 따라 빈 문자열이거나 예상과 다른 값이 들어올 수 있더라고요. 그래서 MIME 타입 검사만 믿지 않고 name.endsWith('.mp4'), name.endsWith('.mp3')처럼 파일명 검사를 ||로 같이 둬서, 둘 중 하나만 신호를 줘도 통과시키게 했어요.
검사 통과 못 하면 alert로만 알려줘요
지금 구현은 형식이 안 맞으면 alert()로만 알려줘요. 구현이 단순하고 바로 눈에 띈다는 장점은 있는데, 브라우저 기본 alert는 스타일을 못 맞추고 스크린리더 사용자한테 전달되는 방식도 사이트 다른 알림이랑 다를 수 있어요. 화면 안 상태 메시지로 표시하는 방식은 브라우저 이미지 업로드 에러 핸들링하는 방법에서 다룬 접근이랑 비교해보실 수 있어요. 이 프로젝트가 아직 그렇게 안 바뀐 건 솔직히 남은 숙제로 적어둘게요.