Spec-Zone.ru › htmx

hx-download

Загружайте файлы с hx-swap='download'

Расширение download сохраняет ответ как загружаемый файл, а не подставляет его в DOM. Оно передаёт тело ответа потоком и генерирует события прогресса.

Оно активируется тремя способами:

  • hx-swap="download" на элементе
  • Сервер отвечает с Content-Disposition: attachment (определяется автоматически, атрибут не требуется)
  • Сервер отвечает с HX-Download: <url> (расширение загружает этот URL как файл, а исходный ответ при этом подставляется обычным образом)

Установка

<script src="https://cdn.jsdelivr.net/npm/htmx.org@4.0.0/dist/htmx.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/htmx.org@4.0.0/dist/ext/hx-download.js"></script>

Использование

Явный стиль подстановки

Используйте hx-swap="download", чтобы всегда обрабатывать ответ как загружаемый файл:

<button hx-get="/files/report.pdf" hx-swap="download">
    Download Report
</button>

Автоопределение по Content-Disposition

Если сервер возвращает Content-Disposition: attachment, расширение автоматически запускает загрузку — hx-swap не требуется:

<button hx-get="/files/report.pdf" hx-target="#result">
    Download Report
</button>
Content-Disposition: attachment; filename="report.pdf"

Заголовок HX-Download

Если серверная часть не может передать файл непосредственно как ответ htmx (например, если нужно перенаправить запрос на отдельную конечную точку загрузки), верните заголовок HX-Download, указывающий на URL файла. Расширение загрузит файл по этому URL, а htmx обработает тело исходного ответа как обычную подстановку:

<button hx-get="/prepare-download" hx-target="#status">
    Download Report
</button>
HX-Download: /files/report.pdf
Content-Type: text/html

<span>Your download has started...</span>

<span> подставляется в #status, а файл по адресу /files/report.pdf загружается одновременно.

Этот подход также позволяет избежать проблемы очистки индикаторов и отключённых элементов, возникающей при использовании HX-Redirect со ссылкой на URL загрузки: индикаторы корректно очищаются после завершения исходного запроса.

Индикатор выполнения

По мере поступления ответа расширение генерирует события на исходном элементе:

<button hx-get="/files/report.pdf" hx-swap="download">
    Download Report
</button>
<progress id="prog" value="0" max="100"></progress>

<script>
document.body.addEventListener("htmx:download:progress", e => {
    document.getElementById("prog").value = e.detail.percent
})
</script>

Для отображения прогресса в процентах сервер должен отправлять заголовок Content-Length. Без него percent будет иметь значение null, и будут доступны только loaded (полученные байты).

События

Событие Данные Описание
htmx:download:start {total} Заголовки ответа получены, начинается передача потоком. total имеет значение null, если отсутствует Content-Length
htmx:download:progress {loaded, total, percent} Генерируется для каждого полученного фрагмента. percent имеет значение null, если отсутствует Content-Length
htmx:download:complete {filename, size} В браузере запущена загрузка файла

Примечания

  • Двоичные файлы (PDF, изображения, архивы) обрабатываются корректно.
  • Имя файла извлекается из заголовка Content-Disposition (filename или filename*=UTF-8''...); если его нет, используется последний сегмент пути URL.
  • Отмена выполняется автоматически с помощью встроенной в htmx обработки прерывания запроса.
  • Для HX-Download индикаторы и отключённые элементы корректно очищаются после завершения исходного запроса — дополнительный запрос выполняется независимо.

Licensed under the Zero-Clause BSD License.
https://four.htmx.org/extensions/hx-download/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API