Веб

Как скачать файл по кнопке без ссылки и серверных изменений

Узнайте, как при клике на кнопку инициировать скачивание файла через JavaScript без использования <a>‑тега и без изменений на сервере. Браузеры поддерживают.

Как можно инициировать скачивание файла, когда я нажимаю кнопку в HTML или запускаю JavaScript, без использования тега <a> и без изменения заголовков сервера?

Я просто хочу простое скачивание, которое ведёт себя так же, как:

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

но вместо ссылки – кнопка, например:

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

Есть ли способ запустить скачивание через JavaScript, примерно так:

javascript
$('#fileRequest').click(function() {
    // код для скачивания
});

Я не ищу «трюков», превращающих ссылку в кнопку, и не хочу использовать серверные скрипты, менять MIME‑типы или заголовки сервера.

Самый простой способ заставить браузер скачать файл по нажатию кнопки — создать скрытый элемент <a> в JavaScript, задать ему href с URL файла (или объект‑URL для Blob), добавить атрибут download и программно «кликнуть» по нему. Это работает во всех современных браузерах, не требует изменений на сервере и ведёт себя как обычная ссылка.


Как это работает

Шаг Что происходит Почему это работает
1. Создать <a> const link = document.createElement('a'); Получаем DOM‑элемент, который можно настроить.
2. Указать файл link.href = 'file.doc'; Браузер знает, где искать данные.
3. Сказать, что это скачивание link.download = ''; Атрибут download заставляет браузер скачать, а не перейти по ссылке.
4. Программный клик link.click(); Имитация клика пользователя, запускающая скачивание.
5. Очистка URL.revokeObjectURL(link.href); (если использовали Blob) Освобождаем память, занятую временным URL.

1️⃣ Скачивание уже существующего файла на сервере

html
<button id="downloadBtn">Скачать!</button>

<script>
document.getElementById('downloadBtn').addEventListener('click', () => {
  const fileUrl = 'file.doc';          // URL относительно страницы
  const link = document.createElement('a');
  link.href = fileUrl;
  link.download = '';                  // По желанию: задать собственное имя
  document.body.appendChild(link);     // Нужно для Firefox
  link.click();                        // Запускаем скачивание
  document.body.removeChild(link);     // Убираем элемент
});
</script>

Нет необходимости в заголовках сервера; браузер автоматически определит MIME‑тип файла.


2️⃣ Скачивание файла, генерируемого «на лету»

Если данные создаются в JavaScript (CSV, JSON, изображение), получаем их как Blob и используем объект‑URL:

html
<button id="genDownload">Скачать CSV</button>

<script>
document.getElementById('genDownload').addEventListener('click', () => {
  const csv = 'Name,Age\nAlice,30\nBob,25';
  const blob = new Blob([csv], { type: 'text/csv' });

  const url = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = url;
  link.download = 'people.csv';        // Предложить имя файла
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);            // Освободить память
});
</script>

3️⃣ Что стоит помнить

Пункт Детали
Политика одного происхождения Если файл берётся с другого домена, сервер должен разрешить CORS.
Поддержка браузерами Атрибут download и URL.createObjectURL работают во всех основных браузерах (Chrome, Edge, Firefox, Safari).
Имя файла Оставив download пустым, браузер использует имя, указанное сервером. Укажите строку, чтобы принудить другое имя.
Очистка памяти После начала скачивания вызывайте URL.revokeObjectURL, чтобы не утечка памяти.
Доступность Кнопка должна иметь aria-label, если текст не описателен.

TL;DR

js
// Клик по кнопке → скачивание файла
document.getElementById('downloadBtn').addEventListener('click', () => {
  const link = document.createElement('a');
  link.href = 'file.doc';   // или URL.createObjectURL(blob)
  link.download = '';       // необязательно: задать собственное имя
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
});

Эта схема даёт «настоящий» скачивание, инициируемый кнопкой, без якорей в разметке, без изменений заголовков сервера и без сторонних библиотек.

Авторы
Проверено модерацией
Модерация