Скачать загруженный пользователем файл JavaScript

Суть проблемы.

Есть <input type="file">. Пользователь кликает и выбирает файл. После выбора файла появляется кнопка "download" при клике на которую начинается скачивание только что выбранного файла. Как именно начать скачивание только что выбранного файла?

Можно, конечно, после клика на "download" ajax'сом сохранять файл на сервере и потом отправлять скачивать на клиенте и удалять через время на бэке, но это мне кажется бредом. Однако клиент требует такой функционал.

Я в замешательстве, быть может у кого есть идеи? Заранее благодарю.


Ответы (2 шт):

Автор решения: UModeL

Для локальной страницы и файлов срабатывает такой вариант:

let oInputFile = document.querySelector('input[type="file"]');

oInputFile.addEventListener('change', function(ev) {
  let aFiles = ev.target.files;
  if (aFiles) {
    let oLink = document.createElement("A");
    oLink.href = URL.createObjectURL(aFiles[0]);
    oLink.innerText = 'Скачать';
    oLink.setAttribute('download', aFiles[0].name);
    document.body.appendChild(oLink);
  }
});
<input type="file">

Для выбора нескольких файлов:

let oInputFile = document.querySelector('input[type="file"]');

oInputFile.addEventListener('change', function(ev) {
  let aFiles = ev.target.files;
  if (aFiles) {
    for (let i = 0; i < aFiles.length; i++) {
      fAddLink(aFiles[i]);
    }
  }
});

function fAddLink(oFile) {
  let oWrap = document.createElement("DIV");
  oWrap.innerHTML = `<span class="txt">${oFile.name}</span>`;

  let oLink = document.createElement("A");
  oLink.className = 'dnl';
  oLink.href = URL.createObjectURL(oFile);
  oLink.setAttribute('download', oFile.name);
  oWrap.insertBefore(oLink, oWrap.firstChild);

  let oSpan = document.createElement("SPAN");
  oSpan.className = 'del';
  oSpan.onclick = function() {
  console.log(this.nextElementSibling.href);
    URL.revokeObjectURL(this.nextElementSibling.href);
    this.parentElement.remove();
  }
  oWrap.insertBefore(oSpan, oWrap.firstChild);

  document.body.appendChild(oWrap);
}
div{height:24px;line-height:24px;margin:4px 0}.del,.dnl{position:relative;margin:1px 3px 4px;display:inline-block;height:18px;width:18px;cursor:pointer}.del:hover,.dnl:hover{filter:drop-shadow(0 0 1px black)}.txt{vertical-align:top;margin-left:5px}.del::before,.del::after{content:'';position:absolute;top:50%;left:50%;width:14px;border:1px solid red}.del::before{transform:translatex(-50%) rotate(45deg)}.del::after{transform:translatex(-50%) rotate(-45deg)}.dnl{height:8px;box-sizing:border-box;border:2px solid blue;border-top:none}.dnl::before,.dnl::after{content:'';position:absolute;bottom:100%;left:50%}.dnl::before{width:9px;border:1px solid blue;transform:translate(-50%,-1px) rotate(90deg)}.dnl::after{height:5px;width:5px;border-left:2px solid blue;border-bottom:2px solid blue;transform:translate(-50%,2px) rotate(-45deg)}
<input type="file" multiple>

→ Ссылка
Автор решения: Stepan Kasyanenko

Берем файл, переводим его в objectURL, сохраняем.

function download() {
  const file = inputFile.files[0];
  if (!file) {
    return;
  }
  const url = window.URL.createObjectURL(file);
  const a = document.createElement('a');
  a.href = url;
  a.download = file.name;
  a.click();
  window.URL.revokeObjectURL(url);
}
<input id="inputFile" type="file">
<button onclick="download()">Download</button>

→ Ссылка