파일 다운로드를 웹 클라이언트에서 구현 할 때 사용자가 파일이름을 지정 할 수 있도록 만들고 싶었고 리서치를 진행했다.
결론은 서버가 파일 이름을 지정해 주는 것이 가장 일반적인 방법이다.
가장 쉬운 방법은 다른 이름으로 저장 창을 강제로 띄워서 사용자가 파일 이름을 넣도록 하는 방법이다.
이 기능은 자바스크립트가 아닌 브라우저에서 지원하는 기능이기 때문에 브라우저 api를 사용해야 한다.
https://developer.mozilla.org/en-US/docs/Web/API/Window/showSaveFilePicker#browser_compatibility
문제는 이 기능이 일부 브라우저에서만 지원하는 기능이라는 것이다.
그러므로 사실 상 사용이 어렵다.
일반적으로 웹 클라이언트에서 파일 다운로드를 진행 할 때에는 눈에 보이지 않는 a태그를 만들어서 클릭하는 방식으로 진행이 되는데, a태그를 만들 때 filename 속성을 주어 클라이언트에서 기본 파일 이름을 지정 할 수 있다.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement/download
다만, 이 방법에도 한계가 있는데 서버 응답헤더에 파일 이름이 설정되면 이 속성을 무시하고 서버에서 지정한 파일 이름으로 다운로드가 진행된다.
https://stackoverflow.com/a/56195387
2번 방법을 약간 응용해서 파일 자체는 자바스크립트로 모두 받도록 하고 저장하는 순간에만 파일이름을 지정하여 저장 할 수 있다.
이렇게 하면 파일 이름을 깔끔하게 변경 할 수 있지만 자바스크립트 내에서 파일 다운로드를 모두 기다려야 하기 때문에 기존 파일 다운로드처럼 파일 다운로드 현황을 브라우저 네이티브에서는 실시간으로 확인 할 수 없다.
아마도 서버에서 파일 크기를 미리 알려준다면 파일 다운로드 로딩 바를 커스텀 하게 만들수는 있지 않을까 싶다.
일단, 최종적으로 성공 한 방법으로 구현 방법은 다음과 같다.
const file = await fetch(data.url); // 따로 처리가 없으면 다운로드 동안 사용자는 아무런 피드백을 받을 수 없다.
const blob = await file.blob();
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
const fileName = window.prompt(
"Please enter the file name"
);
link.download = fileName;
link.href = url;
link.style.display = "none";
document.body.appendChild(link);
link.click();
link.remove();