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]);
  }
};

inputaccept=".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는 스타일을 못 맞추고 스크린리더 사용자한테 전달되는 방식도 사이트 다른 알림이랑 다를 수 있어요. 화면 안 상태 메시지로 표시하는 방식은 브라우저 이미지 업로드 에러 핸들링하는 방법에서 다룬 접근이랑 비교해보실 수 있어요. 이 프로젝트가 아직 그렇게 안 바뀐 건 솔직히 남은 숙제로 적어둘게요.