В этой заметке вы найдете ответы на следующие вопросы:

Как заставить браузер скачать файл по ссылке, а не открыть его?

Заголовок Content-Disposition определяет, как следует обрабатывать содержимое сообщения. Этот заголовок перешел из почтового стандарта MIME. Там этот заголовок имел отношение только к типу содержимого multipart, и описывал распределение частей содержимого. Отсюда и название Disposition. Но в протоколе HTTP он приобрел более широкие функции и сейчас это название не отражает всю полноту его функций.

Базовые функции этого заголовка описаны в документе RFC 2183. Этот заголовок имеет две директивы: inline и attachment. Однако у этого заголовка есть еще одна директива form-data. Это расширение стандарта, которое описано в документе RFC 2388.

inline
Директива inline описывает содержимое, как встроенное. Оно должно быть отображено пользователю автоматически в порядке следования частей содержимого, если этот заголовок используется в частях содержимого. Это значение является значением по умолчанию, поэтому заголовок с этим значением может отсутствовать.

Так, если передать браузеру документ того или иного типа с директивой Content-Disposition: inline или вообще без этого заголовка, то он попытается отобразить документ, в зависимости от того, есть ли у него для этого возможности. Так для текстовых типов и изображений он отобразит их сам, а для типов известных ему приложений (doc, pdf, exl и др.) вызовет соответствующее приложение. И только для неизвестных ему типов он предложит сохранить документ на диске.

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

Параметры этого заголовка, в сочетании со значением attachment, предоставляют дополнительные возможности.

HTTP
Content-Disposition: attachment; filename="8431.jpg"; size=8745;
	creation-date="Wed, 12 Feb 1997 16:29:51 -0500";
	modification-date="Wed, 12 Feb 1997 16:29:51 -0500";
	read-date="Wed, 12 Feb 1997 16:29:51 -0500"

Параметр filename позволяет задать для приложенного файла свое имя. Если этот параметр отсутствует, то файл будет именован в соответствии с именем запрошенного документа.

Параметр size сообщает о размере файла в байтах. Эта информация ни к чему не обязывает.

Параметры creation-date, modification-date, read-date сообщают соответственно о дате создания файла, дате его последнего изменения и дате его последнего чтения. К сожалению, эта информация не заставит браузер (по крайней мере самые популярные, работающие под Windows) при записи файла на диск прописать именно эти свойства файла. При записи на диск, как и обычно, будут установлены текущие даты создания, модификации и доступа.

form-data
Директива form-data является расширением стандарта и используется при отправке POST-запроса с типом содержимого multipart/form-data. О типе multipart/form-data читайте в статье метод POST

Применение .htaccess

Если на вашем сервере Apache установлен модуль mod_headers, то задачу сохранения на диске пользователя определенных файлов можно решить очень легко без использования PHP.

.htaccess
<FilesMatch "\.pdf$">
	Header set Content-disposition "attachment"
</FilesMatch>

В этом примере для всех файлов pdf, которые лежат в том же каталоге, что и данный файл .htaccess, и ниже, будет предложен диалог с возможностью открытия или сохранения файла на диске. Регулярное выражение может быть и не таким простым. Так что выбор условия, с какими файлами отправлять этот заголовок, а с какими нет, достаточно богат.

К сожалению, следует отметить, что не многие провайдеры утруждают себя установкой этого модуля на свои серверы.

Читайте также:

  1. методы запроса: метод POST :: PHP, Apache, кэш

Комментарии:

  1. 20 мая 2015, 08:12

    Михаил

    комментарий No. 1

    Прочитал на другом сайте намного более простой способ через HTML:
    <a href="URL" download="имя_файла">ссылка</a>
    или просто с оригинальным именем файла
    <a href="URL" download>ссылка</a>
    Вообще еще не проверял, но если это работает, то это круто!

    • 20 мая 2015, 08:18

      Автор

      ответ No. 1

      Увы, download очень новый атрибут тега A. Введен он лишь в HTML 5 и проще перечислить где он работает, нежели где он не работает. http://htmlbook.ru/html/a/download По-моему достаточно того, что он абсолютно не работает в IE, чтобы пока о нем забыть. Но на время, ибо в будущем он будет поддерживаться всеми браузерами.

    Ответить на комментарий..

  2. 23 мая 2015, 01:30

    Андрей

    комментарий No. 2

    Атрибут «download», конечно, замечательная вещь, и я не вижу причин не использовать его там, где это действительно необходимо (а браузеры, его не поддерживающие не_нужны). Но есть ряд причин не использовать его для именования скачиваемых с сервера файлов:

    • Файлы получают не только браузеры. Есть wget и всякие менеджеры закачек, которые не смогут определить правильно имя файла без этого заголовка. Даже если оно задано на странице.
    • Пользователь не всегда скачивает ваши файлы кликом по ссылке. Он может скопировать ссылку или добавить её в закладки, а потом перейти по ней. Разумеется, ни о каком атрибуте «download» речи здесь быть не может. Плюс ещё тысяча сценариев, по которым этот атрибут не будет действовать, даже если поддерживается браузером.

    Атрибут «download» необходим в двух случаях:
    1. Для генерируемых прямо на странице файлов
    2. Если ваш сервер (или сервер, на котором лежит файл, который вы предлагаете пользователю скачать) не может в установку кастомных заголовков.

    Ответить на комментарий..

Ваш комментарий