Бесплатный вебинар
«как найти любимую работу»
Подарки на 150 000 ₽ за участие
Живой эфир
Записи не будет!
00:00:00:00
дн.ч.мин.сек.

Принудительное скачивание PDF с сервера: Content-disposition

Быстрый ответ

Для того, чтобы инициировать загрузку файла на жесткий диск пользователя, используйте HTTP-заголовок Content-Disposition: attachment. Обычно настройка производится на сервере посредством кода или конфигурации. В быстрой программе на PHP это выглядит следующим образом:

php
Скопировать код
header('Content-Disposition: attachment; filename="releaseTheKraken.txt"');

Имя файла "releaseTheKraken.txt" – это пример, можно заменить на любое другое, и этот код заставит браузер пользователя начать загрузку файла на его локальный диск.

Кинга Идем в IT: пошаговый план для смены профессии

Подробнее о загрузке файлов

HTML5 к вашим услугам

Для инициирования загрузки файла на стороне клиента можно использовать атрибут download HTML5 в теге <a>:

HTML
Скопировать код
<a href="/path/to/theKraken" download="UnleashedKraken.pdf">Скачать Кракена</a>

Браузер выполнит указание и сохранит файл с заданным именем и расширением.

Подробнее об этом расскажет наш спикер на видео
skypro youtube speaker

Альтернатива для старых браузеров

Если требуется поддержка старых браузеров, таких как MSIE11, не поддерживающих атрибут download, можно создать объект Blob и запустить загрузку вручную:

JS
Скопировать код
function downloadKrakenIE(dataUri, filename) {
  var blob = new Blob([dataUri]);
  window.navigator.msSaveOrOpenBlob(blob, filename);
}

// Пример использования:
downloadKrakenIE(oldSchoolDataUri, 'theKraken');

Универсальный способ загрузки файлов

Из-за различий в поддержке браузеров, стоит объединить все методы в одну функцию, обеспечивающую совместимость:

JS
Скопировать код
function downloadKraken(dataUri, filename) {
  if (window.navigator.msSaveOrOpenBlob) { // Для IE11 и Edge
    downloadKrakenIE(dataUri, filename);
  } else {
    // Для браузеров нового поколения
    var link = document.createElement("a");
    link.href = dataUri;
    link.download = filename;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  }
}

// Готовы к приключениям?
var dataUri = 'data:text/plain;charset=utf-8,Release%20the%20Kraken!';
downloadKraken(dataUri, 'theKraken.txt');

Обработка ошибок при загрузке

Не забывайте обрабатывать исключения при загрузке, чтобы пользователь был в курсе возможных проблем:

JS
Скопировать код
try {
  releaseTheKraken(); // Ваша функция загрузки
} catch(e) {
  alert('Внимание: Кракен не может быть освобожден: ' + e.message);
}

Визуализация

Для наглядности можно представить заголовок Content-disposition как указатели:

Markdown
Скопировать код
Запрос браузера: "Мне нужен этот файл."
Ответ сервера с Content-disposition: "Пожалуйста, сохраните на жесткий диск!"
Без "Content-disposition":
Файл ➡️ 🌐 (открывается в браузере)

С "Content-disposition":
Файл ➡️ 💾 (предлагается к сохранению)

Ключевая мысль: Content-disposition означает "путь к папке с загрузками":

Markdown
Скопировать код
Content-disposition: attachment; filename="guide.pdf" 📄➡️💾
// Без обходных путей. Мы направляемся прямо на ваш жесткий диск.

Избегайте ловушек при загрузке

Кодирование специальных символов

При указании имени файла в заголовке Content-Disposition важно корректно кодировать спецсимволы, чтобы избежать проблем. Используйте rawurlencode в PHP или encodeURIComponent в JavaScript для этого:

php
Скопировать код
header('Content-Disposition: attachment; filename="' . rawurlencode($filename) . '"');

Перезапись заголовков — дело тонкое

Маневрируя с Content-Disposition, обратите внимание, чтобы не перезаписать существующие заголовки. При приоритете последней установки знание особенностей работы с заголовками в выбранном языке или фреймворке оказывается крайне важным.

Рекомендации для гармоничной работы с браузерами

При принудительном запуске загрузки обязательно корректно устанавливайте заголовок Content-Type, соответствующий типу файла:

php
Скопировать код
header('Content-Type: application/pdf');

Полезные материалы

  1. Content-Disposition – HTTP | MDN
  2. RFC 6266 – Использование поля заголовка Content-Disposition
  3. Как закодировать параметр имени файла в заголовке Content-Disposition – Stack Overflow
  4. Атрибут download в HTML – W3Schools
  5. HTTP/1.1: Приложения
  6. GitHub – pillarjs/send: Поддержка статического файлового сервера
Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Какой заголовок HTTP используется для инициирования загрузки файла?
1 / 5