다운로드 API의 일반 동작은 MDN의 a 태그 download 속성 문서를 기준으로 확인했고, 실제 구현은 img-compressor의 ImageCompressor 컴포넌트를 근거로 합니다.

다운로드는 링크 클릭을 흉내 내는 것이다

브라우저에는 “파일을 저장하라”는 별도의 표준 API가 없습니다. 대신 <a> 태그에 download 속성을 붙이면, 그 링크를 새 탭으로 여는 대신 파일로 저장하도록 브라우저에 지시할 수 있습니다. 클라이언트에서 만든 파일을 다운로드시키는 도구는 대부분 이 링크를 코드로 만들고, 클릭까지 자동으로 실행하는 방식을 씁니다.

const downloadFile = (url, filename) => {
  const link = document.createElement('a');
  link.href = url;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
};

이 함수 자체는 img-compressor의 ImageCompressor.tsx에 있는 downloadFile 구현입니다. href에는 Blob URL이나 Data URL을 넣을 수 있고, download 속성값이 사용자에게 저장될 파일명이 됩니다. 링크를 DOM에 추가했다가 클릭 직후 제거하는 이유는, 일부 브라우저가 문서에 붙어 있지 않은 링크의 클릭을 무시하기 때문입니다.

href에는 보통 Blob URL을 쓴다

압축이나 변환 결과처럼 브라우저 메모리 안에서 만든 파일은 URL.createObjectURL(blob)로 임시 URL을 만들어 href에 넣습니다. Data URL도 동작은 하지만, 큰 파일일수록 base64 인코딩 오버헤드가 커지므로 결과 파일 다운로드에는 Blob URL이 더 일반적입니다. 두 방식의 메모리 특성 차이는 Data URL vs Blob URL 글에서 비교합니다.

download 속성이 무시되는 경우

download 속성은 동일 출처(same-origin) 리소스에서 안정적으로 동작합니다. Blob URL이나 Data URL은 애초에 브라우저 메모리 안의 리소스라 이 조건에 해당하지만, 만약 href에 다른 도메인의 URL을 직접 넣으면 브라우저가 다운로드 대신 새 탭에서 열어 버릴 수 있습니다. 크로스오리진 리소스를 다운로드시켜야 한다면, 먼저 fetch로 받아 Blob으로 바꾼 뒤 Blob URL을 만드는 우회가 필요합니다.

여러 파일을 연속으로 받을 때 생기는 문제

일괄 다운로드에서 여러 링크를 반복문으로 한 번에 클릭시키면, 브라우저나 운영체제가 팝업 차단·다운로드 제한 정책으로 일부 파일만 받아지는 경우가 있습니다. img-compressor는 각 다운로드 호출 사이에 인덱스 기반의 짧은 지연을 둬서 이 문제를 줄입니다.

images.forEach((image, index) => {
  setTimeout(() => downloadFile(image.url, image.file.name), index * 120);
});

이 지연은 처리 속도를 최적화하는 코드가 아니라, 브라우저가 짧은 시간에 몰린 다운로드 요청을 정상적으로 처리하도록 여유를 주는 사용자 경험상의 선택입니다. 정확한 지연 값은 브라우저마다 다르게 체감될 수 있어, 실제 배포 환경에서 대상 브라우저로 직접 확인하는 편이 안전합니다.

다운로드가 끝났다고 URL을 바로 지우면 안 되는 경우

다운로드 직후 URL.revokeObjectURL을 호출하고 싶을 수 있지만, 결과 카드를 화면에 계속 보여주는 도구라면 사용자가 같은 파일을 다시 받거나 미리보기를 다시 볼 수 있어야 합니다. 그래서 해제 시점은 다운로드가 아니라 카드 삭제나 전체 초기화 시점으로 미루는 편이 자연스럽습니다. 정리 시점과 이미지·영상 도구의 실제 사례는 Object URL 메모리 누수 가이드에서 다룹니다.

확인해 봐야 할 것

다운로드 로직을 붙인 뒤에는 파일명에 한글, 공백, 확장자 누락이 섞여도 정상적으로 저장되는지, 여러 파일을 연속으로 받았을 때 일부가 누락되지 않는지, 다운로드한 파일을 실제로 열었을 때 손상 없이 재생·조회되는지를 직접 확인하는 편이 안전합니다. 전체 구현은 다중 파일 UI와 상태에서 그대로 읽을 수 있습니다.