Как запустить загрузку файла при нажатии кнопки HTML или JavaScript


434

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

Я хочу простую загрузку файла, которая будет делать то же самое, что и это:

<a href="file.doc">Download!</a>

Но я хочу использовать кнопку HTML, например, одну из следующих:

<input type="button" value="Download!">
<button>Download!</button>

Аналогично, возможно ли вызвать простую загрузку через JavaScript?

$("#fileRequest").click(function(){ /* code to download? */ });

Я определенно не ищу способ создать привязку, которая выглядит как кнопка, использовать какие-либо серверные сценарии или связываться с заголовками серверов или типами mime.


15
Благодаря вам, «как вызвать загрузку файла в javascript» даст ответы намного быстрее для любого будущего поисковика.
Дунайский моряк

Ответы:


278

Для кнопки вы можете сделать

<form method="get" action="file.doc">
   <button type="submit">Download!</button>
</form>

Вы можете сохранить тег формы и просто добавить щелчок к тегу кнопки.
Флориан Лейтгеб

12
не работает как триггер, просто перенаправьте на URL-адрес как тег «a».
fdrv

7
Это работает лучше: <a href="path_to_file" download="proposed_file_name"> Скачать </a>
kscius

11
@kscius даже сегодня атрибут загрузки не поддерживается в IE 11 (теперь он поддерживается в Edge) и не поддерживается в Safari. В 2012 году, когда ответ был опубликован, он не был поддержан ни в одном крупном браузере.
Cfreak

1
В чем разница между наличием якоря со стилем кнопки и формой с кнопкой?
Андрей

444

Вы можете запустить загрузку с downloadатрибутом HTML5 .

<a href="path_to_file" download="proposed_file_name">Download</a>

Куда:

  • path_to_fileэто путь , который разрешается в URL на то же происхождение . Это означает, что страница и файл должны совместно использовать один и тот же домен, поддомен, протокол (HTTP и HTTPS) и порт (если указан). Исключение составляют blob:и data:(которые всегда работают), и file:(которые никогда не работают).
  • proposed_file_nameимя файла для сохранения. Если он пуст, браузер по умолчанию использует имя файла.

Документация: MDN , стандарт HTML на загрузку , стандарт HTML наdownload , CanIUse


37
Не работает с Safari и некоторыми версиями IE
Мохамед Хуссейн

4
Использование комбинации downloadи target="_blank"представляется достаточным для охвата большинства случаев использования. Браузеры, которые понимают, downloadрассматривают его как загрузку, в противном случае он открывается в новой вкладке.
MK10

10
Как это можно применить к объекту кнопки вместо просто тега ?
storm_m2138

8
На самом деле это работает только для URL того же происхождения, что и упомянутые в документах MDN. Это огромное ограничение, если мы стремимся разработать общее решение
Акшат Гупта

6
Вопрос явно просит использовать кнопку вместо ссылки
Квентин

87

HTML:

<button type="submit" onclick="window.open('file.doc')">Download!</button>

8
Лучшее и самое чистое решение. Но вам не нужно никакого дополнительного Javascript здесь. HTML-часть с onclick достаточно.
Флориан Лейтгеб

4
Что делать, если я хочу скачать XML-файл?
g07kore

2
Спасибо за ваш код. Я проверял, он может работать в IE, Chrome, Firefox.
Muthukumar

6
Если у вас есть файл, приемлемый для браузера, например, PDF, он откроется в новой вкладке, чтобы показать диалог загрузки.
WindRider

1
window.open может вызвать блокировку всплывающих окон в браузере, и поэтому не рекомендуется. Вы можете использовать window.location = 'path', хотя это приведет к расположению в том же окне браузера.
Elendurwen

68

С помощью jQuery:

$("#fileRequest").click(function() {
    // // hope the server sets Content-Disposition: attachment!
    window.location = 'file.doc';
});

1
Отлично, спасибо. Вы случайно не знаете, что большинство серверов по умолчанию установят для Content-Disposition значение «attachment»?
Брентонстрин

5
Там нет "большинство". Это полностью зависит. Не полагайтесь на то, что он установлен.
Мэтт Болл

3
Эта проблема сводила меня с ума, и это был единственный вариант, который работал (и поддерживается IE). Я добавлю для всех n00bs, как я, чтобы установить Content-Disposition, все, что вам нужно сделать, это: <? Php header ('Content-Disposition: attachment; filename = "filename.here"'); ?>
user124384

3
Нет JQuery. Период.
Адам Арольд

1
Это Doest работа , если вы пытаетесь загрузить изображение, было бы открыть изображение в браузере
Dheeraj

34

Старый поток, но в нем отсутствует простое решение js:

let a = document.createElement('a')
a.href = item.url
a.download = item.url.split('/').pop()
document.body.appendChild(a)
a.click()
document.body.removeChild(a)

24
@NicholasKyriakides В некотором роде напоминает мне этот драгоценный камень: image.ibb.co/dtkUWJ/Selection_002.png
Стефанос Chrs

@BryanLarsen какая версия FF?
Stefanos Chrs

1
@BryanLarsen Вы правы, Firefox не позволяет этого, не добавив элемент в тело в первую очередь. Спасибо, обновляю ответ
Stefanos Chrs

1
Есть ли способ, чтобы функция javascript была запущена после завершения загрузки? Просто попытайтесь показать сообщение после начала загрузки и удалить сообщение после завершения загрузки.
Мохит Бансал

1
@mohitbansal (un), к счастью, нет, так как он находится на уровне браузера
Stefanos Chrs

23

Вы можете сделать это с помощью «трюка» с невидимым iframe. Когда вы устанавливаете для него «src», браузер реагирует так, как если бы вы щелкнули ссылку с тем же «href». В отличие от решения с формой, оно позволяет встроить дополнительную логику, например, активировать загрузку по истечении времени ожидания, когда выполняются некоторые условия и т. Д.

Это также очень глупо, нет нового мигающего окна / вкладки, как при использовании window.open.

HTML:

<iframe id="invisible" style="display:none;"></iframe>

Javascript:

function download() {
    var iframe = document.getElementById('invisible');
    iframe.src = "file.doc";
}

Это так, по крайней мере, если вы на самом деле присваиваете iframe для document.body.
yxhuvud

1
Похоже, что сейчас это не работает в Chrome, хотя раньше это работало. Интересно, перестаёт ли он периодически работать в разных версиях Chrome.
Добес Вандермер

Работает в Chrome с версии 61.0.3163.100 (официальная сборка) (64-разрядная
версия

Не работает с изображениями в Firefox v57. Он просто отображает изображение в iframe.
Антоний

15

Bootstrap версия

<a class="btn btn-danger" role="button" href="path_to_file"
   download="proposed_file_name">
  Download
</a>

Документировано в Bootstrap 4 , а также работает в Bootstrap 3.


9
Единственное, что это имеет отношение к Bootstrap - это имена классов, это просто сила HTML5.
Мачадо

3
Вопрос явно задает вопрос, как сделать это с помощью кнопки вместо ссылки.
Квентин

2
если бы вы знали что-нибудь о начальной загрузке, вы бы увидели, что это кнопка.
Джон Лорд

11

Я думаю, что это решение, которое вы искали

<button type="submit" onclick="window.location.href='file.doc'">Download!</button>

У меня был случай, когда мой Javascript генерировал файл CSV. Поскольку для его загрузки нет удаленного URL, я использую следующую реализацию.

downloadCSV: function(data){
    var MIME_TYPE = "text/csv";

    var blob = new Blob([data], {type: MIME_TYPE});
    window.location.href = window.URL.createObjectURL(blob);
}

на странице 404 -> смените страницу ошибки на 404. та же проблема, что и в других location.hrefрешениях.
BananaAcid

9

Что о:

<input type="button" value="Download Now!" onclick="window.location = 'file.doc';">

5
Это не работает, если ваш файл, например, является изображением, так как он будет просто открыт в браузере.
Джаггернаут

Возникает еще одна проблема: если файл отсутствует, он перемещается по всей странице на страницу 404
Хьюз,

7

Вы можете скрыть ссылку на скачивание и нажать кнопку.

<button onclick="document.getElementById('link').click()">Download!</button>
<a id="link" href="file.doc" download hidden></a>

Чтобы это работало в Firefox, ресурс должен находиться в том же домене, что и документ. Установка заголовков CORS не помогает.
Антоний

2
Никогда не делайте этого
Wannes

@ Почему бы и нет?
Starwarswii

4

Если вы ищете ванильное решение JavaScript (без jQuery) и без использования атрибута HTML5, вы можете попробовать это.

const download = document.getElementById("fileRequest");

download.addEventListener('click', request);

function request() {
    window.location = 'document.docx';
}
.dwnld-cta {
    border-radius: 15px 15px;
    width: 100px;
    line-height: 22px
}
<h1>Download File</h1>
<button id="fileRequest" class="dwnld-cta">Download</button>


1

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

JS, чтобы обновить атрибут действия формы:

function setFormAction() {
    document.getElementById("myDownloadButtonForm").action = //some code to get the filename;
}

Вызов JS для обновления атрибута действия формы:

<body onLoad="setFormAction();">

Форма тега с кнопкой отправки:

<form method="get" id="myDownloadButtonForm" action="">
    Click to open document:  
    <button type="submit">Open Document</button>
</form>

Следующее НЕ работает:

<form method="get" id="myDownloadButtonForm" action="javascript:someFunctionToReturnFileName();">

возможно, потому что, если у вас есть файл во время загрузки, вы не можете просто визуализировать действие на сервере, используя шаблонизатор? зачем нужен js код?
Андрей

1

Если вы не можете использовать форму, подойдет другой подход с downloadjs . Downloadjs использует блоб и html 5 файловый API под капотом:

{downloadjs (url, filename)}) />

* это синтаксис JSX / реагировать, но может использоваться в чистом HTML


Чтобы избежать проблем с CORS для изображений в других доменах, поместите crossorigin = "anonymous" в тег img, например: <img src = "image.png" crossorigin = "anonymous" />
Джонатан Харрис

0

В любом месте между тегами <body>и </body>тегами вставьте кнопку, используя следующий код:

<button>
    <a href="file.doc" download>Click to Download!</a>
</button>

Это обязательно сработает!


1
Для Chrome это отличное решение
Айк Арамян

1
Также не работает в Safari: W3 Schools
Alex

2
Не работать в браузерах MS - довольно большая проблема, и Chrome не всегда будет решением.
SudoKid

Вы не можете поместить ссылку внутри кнопки в HTML
Квентин,

0

Еще один способ сделать это, если у вас есть сложный URL-адрес, например, file.doc?foo=bar&jon=doeдобавить скрытое поле внутри формы

<form method="get" action="file.doc">
  <input type="hidden" name="foo" value="bar" />
  <input type="hidden" name="john" value="doe" />
  <button type="submit">Download Now</button>
</form>

вдохновил на ответ @Cfreak, который не является полным


0

Вы можете добавить тег без текста, но со ссылкой. и когда вы нажимаете кнопку, как в коде, просто запустите функцию $ ("yourlinkclass"). click ().


-1

атрибут загрузки сделать это

 <a class="btn btn-success btn-sm" href="/file_path/file.type" download>
     <span>download </span>&nbsp;<i class="fa fa-download"></i>
 </a>

2
Мне нравится ваш ответ
Джордж С.

2
Вопрос явно задает вопрос, как сделать это с помощью кнопки вместо ссылки.
Квентин

-6

Если вы используете <a>тег, не забудьте использовать весь URL, который ведет к файлу, то есть:

<a href="http://www.example.com/folder1/file.doc">Download</a>

Я не думаю, что это проблема здесь. Также «абсолютный» путь не требуется, если ссылка находится в том же пути, что и файл.
Ракета Хазмат

@Rocket - вы, конечно, правы относительно абсолютного пути, однако это лучший способ убедиться в том, что он правильный. Я оставлю это на OP, чтобы решить, было ли это полезно -
Марк

Вопрос явно задает вопрос, как сделать это с помощью кнопки вместо ссылки.
Квентин

атрибут загрузки отсутствует в этом решении. Даже после добавления атрибутов загрузки он не будет работать для междоменного домена.
Шариф

-6

Для меня кнопка добавления вместо якорного текста работает очень хорошо.

<a href="file.doc"><button>Download!</button></a>

Это может быть не совсем нормально по большинству правил, но выглядит довольно хорошо.


5
Это работает только потому, что ваш браузер не поддерживает файлы .doc.
Дизайн Адриана

Ваш HTML неверен. <a>элементы не могут содержать <button>элементы.
Квентин

всегда ли так было? Этому ответу было два года, когда вы это прокомментировали.
Джон Лорд
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.