Як викликати завантаження файлу при натисканні кнопки 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>

Ви можете зберегти тег форми і просто додати onclick до тегу кнопок.
Флоріан Лейтгеб

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 Standard для завантаження , HTML Standard ondownload , CanIUse


37
Не працюйте з Safari та певними версіями IE
Мохамед Хуссейн

4
Використання комбінації downloadта, target="_blank"здається, є достатнім для покриття більшості випадків використання. Веб-браузери, які розуміють, downloadтрактують це як завантаження, інакше він відкриється на новій вкладці.
MK10

10
Як це можна застосувати до об’єкта кнопки замість просто тегу ?
storm_m2138

8
Насправді це працює лише для URL-адрес того самого походження, що згадуються в документах MDN. Це величезне обмеження, якщо ми хочемо розробити загальне рішення
Akshat Gupta

6
Питання прямо вимагає використовувати кнопку замість посилання
Квентін

86

HTML:

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

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

4
Що робити, якщо я хочу завантажити XML-файл?
g07kore

2
Дякуємо за Ваш код. Я протестував, він може працювати в IE, Chrome, Firefox.
мутхукумар

6
Якщо у вас є прийнятний браузером файл, як PDF, він відкриється на новій вкладці, щоб відобразити діалогове вікно завантаження.
WindRider

1
window.open може викликати блокування спливаючих вікон у веб-переглядачі, і тому не рекомендується. Ви можете використовувати window.location = 'path', хоча це переходитиме до місця у тому ж вікні браузера.
Елендурвен

68

За допомогою jQuery:

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

1
Ідеально, дякую. Чи знаєте ви, чи більшість серверів за замовчуванням встановить "Вкладення" для "Вкладення"?
brentonstrine

5
Немає "самого". Це повністю залежить. Не покладайтеся на те, що він встановлений.
Метт Бал

3
Це питання спричинило мене балістично, і це був єдиний варіант, який працював (і підтримується IE). Я додам для будь-яких n00bs, як я, щоб встановити Content-Disposition, все, що вам потрібно зробити, це: <? Php header ('Content-Disposition: attachment; filename = "filename.here"'); ?>
користувач124384

3
Жодних запитів. Період.
Адам Арольд

1
Якщо ви намагаєтеся завантажити зображення, це відкриє зображення у браузері
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
Stefanos Chrs

@BryanLarsen, яка версія FF?
Стефанос Чрс

1
@BryanLarsen Ви маєте рацію, Firefox не дозволяє цього, не додавши елемент спочатку до тіла. Дякую, оновивши відповідь
Стефанос Чрс

1
Чи існує спосіб запускати функцію javascript після закінчення завантаження? Просто намагаюся показати повідомлення після запуску та видалення повідомлення після завершення завантаження.
mohit bansal

1
@mohitbansal (un) на щастя ні, оскільки це на рівні браузера
Stefanos Chrs

23

Ви можете зробити це "фокусом" з невидимим кадром. Коли ви встановите на нього "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.
Dobes Vandermeer

Працює в Chrome станом на версію 61.0.3163.100 (офіційна збірка) (64-розрядна)
AndrewBenjamin

Не працює з зображеннями в Firefox v57. Він просто виводить зображення у рамку iframe.
Антоній

15

Версія для завантаження

<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
Це не працює, якщо, наприклад, у вашому файлі є зображення, оскільки воно просто відкриється у браузері.
Juggernaut

Виникає ще одна проблема, яка полягає в тому, що якщо файл відсутній, він переходить на всю сторінку до сторінки 404
Х'ют

7

Ви можете приховати посилання для завантаження і змусити кнопку натиснути його.

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

Щоб це працювало в Firefox, ресурс повинен знаходитися на тому ж домені, що і документ. Налаштування заголовків CORS не допомагає.
Антоній

2
Ніколи не робіть цього
Wannes

@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 використовує API blob та html 5 під кришкою:

{downloadjs (URL, ім'я файлу)}) />

* це синтаксис jsx / react, але його можна використовувати в чистому 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
Quentin

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>

Я не думаю, що тут проблема. Також "абсолютний" шлях не потрібен, якщо посилання знаходиться в тому ж шляху, що і файл.
Ракета Hazmat

@Rocket - ви, звичайно, правильні щодо абсолютного шляху, однак це найкращий спосіб переконатися, що це правильно. Я залишу це на ОП, щоб вирішити, чи було це корисно -
Марк

Питання явно запитує, як це зробити за допомогою кнопки замість посилання.
Квентін

атрибут завантаження відсутній у цьому рішенні. Навіть після додавання атрибутів завантаження він не працюватиме для крос-домену.
s sharif

-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.