Скачать файл, используя Javascript / jQuery - PullRequest
299 голосов
/ 20 сентября 2010

У меня очень похожее требование указано здесь .

Мне нужно, чтобы браузер пользователя запускал загрузку вручную, когда $('a#someID').click();

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

Вместо этого я хочу открыть загрузку в новом окне / вкладке.Как это возможно?

Ответы [ 25 ]

355 голосов
/ 20 сентября 2010

Используйте невидимку <iframe>:

<iframe id="my_iframe" style="display:none;"></iframe>
<script>
function Download(url) {
    document.getElementById('my_iframe').src = url;
};
</script>

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

Если вы хотите открыть его только на новой вкладке, единственный способ сделать это - щелкнуть по ссылке с атрибутом target, установленным в _blank.

В jQuery:

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

При нажатии на эту ссылку файл загружается в новую вкладку / окно.

145 голосов
/ 23 марта 2012

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 разработчик может легко показать модал, сообщающий пользователю, что происходит загрузка файла, расформировать модал после начала загрузки или даже дружески проинформировать пользователя о том, что произошла ошибка. См. Demo для примера этого. Надеюсь, это кому-нибудь поможет!

Вот простая демонстрация варианта использования плагина source с обещаниями. Демонстрационная страница включает в себя множество других примеров «лучшего UX».

$.fileDownload('some/file.pdf')
    .done(function () { alert('File download a success!'); })
    .fail(function () { alert('File download failed!'); });
118 голосов
/ 11 апреля 2014
function downloadURI(uri, name) 
{
    var link = document.createElement("a");
    link.download = name;
    link.href = uri;
    link.click();
}

Проверьте, будут ли ваши целевые браузеры плавно запускать приведенный выше фрагмент кода:
http://caniuse.com/#feat=download

64 голосов
/ 25 июня 2015

Я удивлен, что мало кто знает об атрибуте загрузки для элементов.Пожалуйста, помогите распространить информацию об этом!Вы можете иметь скрытую ссылку html и подделать клик по ней.Если ссылка html имеет атрибут загрузки, она загружает файл, а не просматривает его, несмотря ни на что.Вот кодОн загрузит изображение кота, если сможет его найти.

document.getElementById('download').click();
<a href="https://docs.google.com/uc?id=0B0jH18Lft7ypSmRjdWg1c082Y2M" download id="download" hidden></a>

Примечание. Это поддерживается не во всех браузерах: http://www.w3schools.com/tags/att_a_download.asp

46 голосов
/ 13 августа 2015

Я рекомендую использовать html5 для загрузки вместо jQuery:

<a href="your_link" download> file_name </a>

Это загрузит ваш файл, не открывая его.

20 голосов
/ 01 октября 2012

Если вы уже используете jQuery, вы можете использовать его для создания меньшего фрагмента
JQuery-версия ответа Эндрю:

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');
12 голосов
/ 28 апреля 2016

Работает на Chrome, Firefox и IE8 и выше.

var link=document.createElement('a');
document.body.appendChild(link);
link.href=url ;
link.click();
10 голосов
/ 27 августа 2016

Простой пример использования iframe

function downloadURL(url) {
    var hiddenIFrameID = 'hiddenDownloader',
        iframe = document.getElementById(hiddenIFrameID);
    if (iframe === null) {
        iframe = document.createElement('iframe');
        iframe.id = hiddenIFrameID;
        iframe.style.display = 'none';
        document.body.appendChild(iframe);
    }
    iframe.src = url;
};

Затем просто вызовите функцию, где вы хотите:

downloadURL('path/to/my/file');

10 голосов
/ 18 января 2017

Только через семь лет здесь приходит решение jQuery с одной строкой, использующее форму вместо фрейма или ссылки:

$('<form></form>')
     .attr('action', filePath)
     .appendTo('body').submit().remove();

Я проверял это в

  • Chrome 55
  • Firefox 50
  • Edge IE8-10
  • iOS 10 (Safari / Chrome)
  • Android Chrome

Если кто-нибудьзнает о каких-либо недостатках с этим решением, я был бы очень рад услышать о них.


Полная демонстрация:

<html>
<head><script src="https://code.jquery.com/jquery-1.11.3.js"></script></head>
<body>
<script>
    var filePath = window.prompt("Enter a file URL","http://jqueryui.com/resources/download/jquery-ui-1.12.1.zip");
    $('<form></form>').attr('action', filePath).appendTo('body').submit().remove();
</script>
</body>
</html>
5 голосов
/ 08 января 2019

Это может быть полезно, если вам не требуется переходить на другую страницу.Это базовая функция javascript, поэтому ее можно использовать на любой платформе, где бэкэнд находится в Javascript

window.location.assign('any url or file path')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...