Изтегляне на файл с помощта на Javascript/jQuery

Имам много подобно изискване, посочено тук.

Трябва да накарам браузъра на потребителя да започне изтегляне ръчно, когато $('a#someID').click();

Но не мога да използвам метода window.href, тъй като той замества съдържанието на текущата страница с файла, който'се опитвате да изтеглите.

Вместо това искам да отворя изтеглянето в нов прозорец/таб. Как е възможно това?

Решение

Използвайте невидим <iframe>:


<script>
function Download(url) {
    document.getElementById('my_iframe').src = url;
};
</script>

За да принудите браузъра да изтегли файл, който иначе би могъл да визуализира (например HTML или текстови файлове), е необходимо сървърът да зададе MIME Type на файла на безсмислена стойност, като например application/x-please-download-me или алтернативно application/octet-stream, което се използва за произволни двоични данни.

Ако искате да го отворите само в нов таб, единственият начин да го направите е потребителят да щракне върху връзка, чийто атрибут target е зададен на _blank.

В jQuery:

$('a#someID').attr({target: '_blank', 
                    href  : 'http://localhost/directory/file.pdf'});

При всяко щракване върху тази връзка файлът ще бъде изтеглен в нов таб/прозорец.

Коментари (21)

Актуализация на съвременните браузъри за 2019 г.

Това е подходът, който сега бих препоръчал с няколко уговорки:

  • Необходим е сравнително модерен браузър.
  • Ако се очаква файлът да бъде много голям, вероятно трябва да направите нещо подобно на първоначалния подход (iframe и cookie), тъй като някои от операциите по-долу вероятно биха могли да изразходват системна памет, голяма поне колкото сваления файл, и/или други интересни странични ефекти върху процесора.
fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(resp => resp.blob())
  .then(blob => {
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.style.display = 'none';
    a.href = url;
    // the filename you want
    a.download = 'todo-1.json';
    document.body.appendChild(a);
    a.click();
    window.URL.revokeObjectURL(url);
    alert('your file has downloaded!'); // or you know, something with better UX...
  })
  .catch(() => alert('oh no!'));

2012 оригинален подход, базиран на jQuery/iframe/cookie

Създадох плъгина jQuery File Download (Demo) (GitHub), който също би могъл да помогне във вашата ситуация. Тя работи доста подобно на iframe, но има някои страхотни функции, които са ми доста полезни:

  • Много лесно се настройва с хубави визуални ефекти (jQuery UI Dialog, но не е задължително), всичко е тествано също

  • Потребителят никога не напуска същата страница, от която е започнал изтеглянето на файла. Тази функция става изключително важна за съвременните уеб приложения

  • Функциите successCallback и failCallback ви позволяват да посочите ясно какво вижда потребителят във всяка от двете ситуации

  • В съчетание с jQuery UI разработчикът може лесно да покаже модал, който да информира потребителя, че се извършва изтегляне на файл, да разпусне модала, след като изтеглянето започне, или дори да информира потребителя по приятелски начин, че е възникнала грешка. Вижте Demo за пример за това. Надявам се това да помогне на някого!

Ето една проста демонстрация на случай на употреба, в която се използва приставката източник с обещания. Страницата демо включва и много други, 'по-добри UX' примери.

$.fileDownload('some/file.pdf')
    .done(function () { alert('File download a success!'); })
    .fail(function () { alert('File download failed!'); });
Коментари (10)

Ако вече използвате jQuery, можете да се възползвате от него, за да създадете по-малък фрагмент jQuery версия на отговора на Andrew's:

var $idown;  // Keep it outside of the function, so it's initialized once.
downloadURL : function(url) {
  if ($idown) {
    $idown.attr('src',url);
  } else {
    $idown = $('<iframe>', { id:'idown', src:url }).hide().appendTo('body');
  }
},
//... How to use it:
downloadURL('http://whatever.com/file.pdf');
Коментари (7)