Атрибут download превращает ссылку из «открыть» в «сохранить»: вместо перехода по адресу браузер скачивает файл. Его записывают в теге <a> и в теге <area> . Значение необязательно, а если оно есть, то задаёт название сохраняемого файла. Ниже разобрано, как атрибут выбирает название, почему он молчит на ссылках чужого сайта и как скачать файл, которого на сервере нет и который страница создала сама.
<a href="/files/price.pdf" download>Скачать прайс</a>
В этой статье
- Атрибут download в HTML: что делает и у каких тегов работает
- Значение атрибута download: как задать название скачиваемого файла
- Атрибут download и открытие файла: когда браузер скачивает, а когда показывает
- Атрибут download и чужой сайт: почему ссылка не скачивает файл
- Атрибут download и blob: как скачать файл, созданный в браузере
- Как прочитать и изменить атрибут download через JavaScript
- Частые ошибки с атрибутом download
- Шпаргалка по атрибуту download
Атрибут download в HTML: что делает и у каких тегов работает
Без download браузер сам решает, что сделать с файлом по ссылке: показать его на странице или скачать. Атрибут снимает это решение с браузера, и файл сохраняется на устройство. Работает он только у двух тегов, у которых есть адрес для перехода.
| Тег | Что делает download | Пример записи |
|---|---|---|
<a> | Файл по ссылке скачивается, а не открывается | <a href="/price.pdf" download> |
<area> | То же для области на карте-изображении | <area href="/price.pdf" download alt="Прайс"> |
<link> , <button> , <img> | Не поддерживают: такого атрибута у них нет | <button download> ничего не сделает |
Кнопке скачивание атрибутом не задать. Если нужна кнопка «Скачать», делают ссылку и оформляют её как кнопку. Подробности есть в стандарте HTML .
Значение атрибута download: как задать название скачиваемого файла
У download есть запись без значения и запись со значением. От неё зависит название файла: без значения браузер берёт его из адреса, со значением использует то, что вы написали. Название можно писать на кириллице и с пробелами.
| Запись | Какое название получит файл | Пример записи |
|---|---|---|
| Без значения | Название из адреса. У файла, созданного в браузере, названия в адресе нет, поэтому будет случайный набор букв и цифр | <a href="/price.pdf" download> |
| Со значением | То, что вы написали | <a href="/price.pdf" download="Цены.pdf"> |
| Пустое значение | То же, что без значения: атрибут есть, а названия нет | <a href="/price.pdf" download=""> |
| Любое слово | Значение всегда считается названием, даже если это false: файл получит название false | <a href="/price.pdf" download="false"> |
Недопустимые в названиях файлов символы браузер обычно заменяет: слеш и двоеточие превращаются в подчёркивание, поэтому папку через download не создать. Если в названии нет расширения, браузер часто дописывает его по типу файла. Надёжнее всегда писать расширение самому.
<a href="1.txt" download="notes.txt">...</a>
<a href="1.txt" download="my file.txt">...</a>
<a href="1.txt" download="a/b.txt">...</a>
<a href="1.txt" download="noext">...</a>
Пример: как записанное значение становится названием файла
Нажмите каждую ссылку и посмотрите в списке загрузок, как назван файл. Слеш в третьем названии браузер заменит, у четвёртого обычно допишет расширение. Файл создала сама страница.
Атрибут download и открытие файла: когда браузер скачивает, а когда показывает
Если download нет, судьбу файла решает браузер. Текст, картинку и HTML-страницу он обычно открывает прямо во вкладке, для остальных типов предлагает сохранить. С download скачиваются все эти файлы. Это удобно для того, что читатель захочет сохранить, а не посмотреть: текст, картинка, архив с заготовками.
<a href="primer.txt" download>Скачать</a>
<a href="primer.txt" target="_blank">Открыть во вкладке</a>
Пример: скачать или открыть один и тот же файл
Первая ссылка сохраняет файл, вторая открывает его в новой вкладке. Файл один и тот же, его создала сама страница.
Если рядом с download у ссылки есть target="_blank", новая вкладка обычно не открывается: файл просто скачивается. Писать оба атрибута нет смысла, достаточно download.
Атрибут download и чужой сайт: почему ссылка не скачивает файл
Самая частая причина, почему download «не работает», в том, что файл лежит на другом сайте. Браузер выполняет атрибут только для файлов того же сайта, а также для адресов blob: и data:, которые создала сама страница. Для чужого сайта атрибут игнорируется, и ссылка работает как обычная.
| Откуда файл | Что делает download | Пример записи |
|---|---|---|
| С того же сайта | Скачивает файл | <a href="/price.pdf" download> |
Создан в браузере (blob:, data:) | Скачивает файл | <a href="blob:..." download="a.txt"> |
| С чужого сайта | Игнорируется: браузер переходит по ссылке как обычно | <a href="https://example.com/a.pdf" download> |
<a href="https://example.com/" download="primer.html"
target="_blank">Чужой сайт</a>
Пример: чужой сайт и файл, созданный в браузере
Первая ссылка откроет чужой сайт в новой вкладке, несмотря на download. Вторая сохранит файл, потому что создала его сама страница.
Есть и обратная сторона. Сервер сам может приказать браузеру скачать файл, отправив заголовок ответа Content-Disposition. Он главнее атрибута: если в заголовке записано название файла, браузер использует его, а не значение download.
Content-Disposition: attachment; filename="report.pdf"
| Что задано | Название файла при скачивании | Пример записи |
|---|---|---|
| Только адрес | Из адреса | href="/files/a.pdf" |
Адрес и download | Из download | download="Прайс.pdf" |
Адрес, download и заголовок сервера | Из заголовка | filename="report.pdf" |
Значит, если название файла не меняется, как ни пиши значение, смотрите заголовки ответа сервера: это вопрос настройки сервера, а не HTML.
Атрибут download и blob: как скачать файл, созданный в браузере
Файл не обязан лежать на сервере. Страница может сама собрать его из текста, таблицы или картинки и отдать читателю. Для этого создают blob, то есть объект с содержимым файла, получают на него временный адрес и записывают этот адрес в ссылку с download. Так работают кнопки «Скачать как текст», «Экспорт в JSON» и «Сохранить картинку».
const blob = new Blob(["Привет"], { type: "text/plain" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "hello.txt";
a.click();
setTimeout(() => URL.revokeObjectURL(url), 1000);
Пример: кнопка, которая создаёт и скачивает файл
Измените текст и название файла и нажмите «Скачать файл»: браузер сохранит файл с вашим текстом и названием. Размер пересчитывается сам.
Вызов URL.revokeObjectURL(url) освобождает память: пока адрес не отозван, браузер держит файл до закрытия страницы. Для маленьких файлов это можно не делать, для больших лучше отозвать адрес после клика, с небольшой задержкой. Картинку из canvas скачивают тем же способом: метод toBlob отдаёт blob, а дальше всё как выше.
canvas.toBlob((blob) => {
const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = "picture.png";
a.click();
});
Для совсем маленьких текстов подходит и адрес data:, где содержимое записано прямо в ссылке. Но у таких адресов есть ограничения по размеру, а blob свободнее и удобнее.
Как прочитать и изменить атрибут download через JavaScript
В JavaScript у ссылки есть свойство download. Если атрибута нет, оно возвращает пустую строку, и от пустого значения такой результат не отличить, поэтому наличие атрибута проверяют методом hasAttribute. Запись в свойство создаёт атрибут в разметке, а удаляет его removeAttribute.
const link = document.querySelector("a");
link.download; // "" если атрибута нет
link.hasAttribute("download"); // true или false
link.download = "report.txt"; // атрибут появился
link.removeAttribute("download");
Пример: чтение и запись свойства download
Нажимайте кнопки: таблица показывает свойство, наличие атрибута и его значение. «Нажать на ссылку» сохраняет файл, пока атрибут есть, а без него файл откроется в новой вкладке.
Частые ошибки с атрибутом download
Большая часть жалоб на download сводится к чужому файлу или заголовку сервера. Сам атрибут простой, но без href ему нечего скачивать.
| Ошибка | Что происходит | Как исправить |
|---|---|---|
download у ссылки на чужой сайт | Атрибут игнорируется, ссылка открывается как обычная | Скачивать со своего сайта или настроить на сервере Content-Disposition |
Ждать смену названия, когда сервер шлёт Content-Disposition | Побеждает название из заголовка | Поменять заголовок на сервере |
download="папка/файл.txt" | Слеш заменяется, папка не создаётся | Писать название без путей |
download="noext" без расширения | Браузер дописывает расширение сам, и не всегда то, что нужно | Писать расширение: download="notes.txt" |
download="false", чтобы «выключить» скачивание | Значение считается названием: файл сохранится как false | Убрать атрибут целиком |
<button download> | Ничего не происходит: у кнопки такого атрибута нет | Ссылка с download, оформленная как кнопка |
<a download> без href | Скачивать нечего: ссылка без адреса никуда не ведёт | Добавить href |
Совсем не отзывать URL.createObjectURL для больших файлов | Файл висит в памяти до закрытия страницы | Отозвать адрес после клика, с небольшой задержкой |
| Ссылка «Скачать» без указания формата и размера | Читатель не знает, что скачает и сколько это весит | Писать «Скачать прайс (PDF, 2 МБ)» |
Шпаргалка по атрибуту download
Всё главное об атрибуте download в одной таблице.
| Что | Как работает | Пример записи |
|---|---|---|
| Где пишут | У a и area | <a href="/a.pdf" download> |
| Без значения | Файл скачивается под названием из адреса | download |
| Со значением | Значение становится названием файла | download="Цены.pdf" |
| Недопустимые символы | Браузер заменяет их, папку создать нельзя | download="a/b.txt" |
Свой сайт, blob:, data: | Работает | href="blob:..." |
| Чужой сайт | Игнорируется, переход как по обычной ссылке | href="https://example.com/a.pdf" |
Заголовок Content-Disposition | Главнее атрибута, особенно в названии файла | filename="report.pdf" |
С target="_blank" | Вкладка обычно не открывается, файл скачивается | download target="_blank" |
| JavaScript | link.download это строка, пустая, пока атрибута нет | link.download = "a.txt" |