Принудительное скачивание файла вместо просмотра в браузере

Обновлено: 03.07.2024

Есть ли способ принудительно открыть PDF-файлы в браузере, если опция «Отображать PDF в браузере» не отмечена?

Я попытался использовать тег embed и iframe, но он работает только тогда, когда эта опция отмечена.

Что я могу сделать?

Чтобы файл был загружен, а не просмотрен:

Кавычки вокруг имени файла требуются, если имя файла содержит специальные символы, например, filename[1].pdf которые могут нарушить способность браузера обрабатывать ответ.

Для принудительной загрузки я использую Content-Type: application / octet-stream. @ PapickG.Taboada, но тогда система пользователя может не знать тип файла. Например, некоторые пользователи, возможно, выбрали «Всегда открывать файлы этого типа» для файлов PDF. Возможно, если вы хотите переопределить пользовательские предпочтения, тогда можно использовать octet-stream, но указание правильного типа и предлагаемого имени файла - это «правильный» способ обеспечить загрузку. Привет @ColinM Я немного запутался здесь . у нас проблемы с рендерингом PDF, он просто дает зашифрованный текст. где мы устанавливаем Content-Type: application / pdf Content-Disposition: встроенный; "filename.pdf"? потому что мы загружаем его, используя код angular-js. Итак, мой вопрос: должен ли тип контента быть установлен перед загрузкой? А также, мы получаем только ссылку от бэкэнд-команды, URL, который дает путь к файлу, который мы открываем в новой вкладке, используя: window.open (url, '_blank'). Focus (); @ColinM Спасибо, приятель, ты правильно сказал, что проблема, когда мы отлаживали, была связана с типом mime при загрузке файлов. Это должно сделать внутренняя команда. Я пытался получить коды о том, как добавить заголовки в сценарии Java, но не удалось. Спасибо, поскольку я получил реальную идею очищен от вас . :)

Если вы используете HTML5 (и я думаю, что в настоящее время все используют это), есть атрибут с именем download .

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

Если у вас есть контроль над кодом сервера, вы должны использовать 'attachchement', поскольку это позволит использовать тот же код генерации имени файла. Если у вас нет контроля над сервером, это хорошее решение. Важно отметить, что это не работает между доменами (например, политика одного и того же происхождения мешает). При загрузке из одного домена атрибут загрузки не будет работать, если содержимое хранится в другом домене. CORS может пропустить этот контент (не проверял). Да понял! : \ Я неправильно понял вопрос и ответил. Но многие люди приземляются здесь, находя только противоположность, поэтому не отредактировали / удалили ответ.

Правильный тип application/pdf для PDF, а не application/force-download . Это выглядит как хак для некоторых старых браузеров. Всегда используйте правильный mimetype, если можете.

Если у вас есть контроль над кодом сервера:

  • Принудительная загрузка / приглашение: используйте header("Content-Disposition", "attachment; filename=myfilename.myextension");
  • Браузер пытается открыть его: использовать header("Content-Disposition", "inline; filename=myfilename.myextension");

Нет контроля над кодом сервера:

  • Используйте атрибут загрузки HTML5 . Он использует пользовательское имя файла, указанное на стороне просмотра.

ПРИМЕЧАНИЕ. Я предпочитаю указывать имя файла на стороне сервера, поскольку у вас может быть больше информации и вы можете использовать общий код.

  • Open with Desktop
  • View raw
  • Copy raw contents Copy raw contents Loading

Copy raw contents

Copy raw contents

Коллекция .htaccess сниппетов, собранных в одном месте.

Дисклеймер: Перед тем, как использовать сниппет в файле .htaccess , в большинстве случаев необходимо сделать небольшие коррекции (поменять название папки или файла, изменить URL и т.д.). Используйте сниппеты на свой страх и риск.

ВАЖНО: В Apache 2.4 появилось несколько важных изменений, особенно в конфигурации управления доступами. Чтобы узнать больше об этих и других изменениях перейдите по этой ссылке, а также просмотрите это ишью.

Что мы делаем? Здесь собраны самые полезные сниппеты для файла .htaccess из всего интернета (например, много разных приемов из Apache Server Configs мы собрали в одном месте). Не исключено, что мы могли что-то упустить. Если вы заметили где-то ошибки или несоответствия, пожалуйста, сообщите нам об этом или сделайте Pull Request. Подробнее о том, как помочь проекту и делать Pull Request'ы, вы можете прочитать в этой статье на Хабрахабр.

Rewrite и Redirect

Примечание: Предполагается, что модуль mod_rewrite установлен и включен.

Перенаправление с без www на с www

Это работает для любого домена. Источник

Перенаправление с www на без www

Это вечная тема для дискуссий - использовать или не использовать www, но если вы поклонник "чистых" доменов, то:

Полезно, если вы имеете прокси перед вашим сервером для TLS.

Вставить завершающий слэш

Удалить завершающий слэш

Редирект со страницы на страницу

Редирект с использованием RedirectMatch

Алиас для определенной директории

Алиас пути до скрипта

В этом примере приведён файл index.fcgi , который лежит в каталоге и все запросы к этому каталогу, которые потерпели неудачу из-за отсутствия файла/директории будут перенаправлены на скрипт index.fcgi . Это хорошо, если вы хотите, чтобы baz.foo/some/cool/path обрабатывался скриптом baz.foo/index.fcgi (который также поддерживает запросы на baz.foo ) в тоже время поддерживается baz.foo/css/style.css и другое подобное. Узнать истинный путь можно из переменной окружения PATH_INFO, которая доступна в скриптах.

Это менее эффективная версия директивы FallbackResource (поскольку использование mod_rewrite сложнее, чем просто обработка директивой FallbackResource ), но также и более гибкое.

Редирект всего сайта

Использовать чистые URL

Запретить доступ всем

Подождите-ка, этот сниппет заблокирует доступ к сайту даже для вас! Сейчас исправим это.

Запретить доступ всем, кроме.

xxx.xxx.xxx.xxx - это ваш IP. Если вы замените последние три цифры, например, на 0/12 , этим вы определите диапазон IP внутри этой сети и это оградит вас от проблемы перечислять по отдельности все разрешённые IP. Источник

И, естественно, противоположная функция к этой:

Разрешить доступ всем, кроме.

Запретить доступ к скрытым файлам и директориям

Скрытые файлы и директории (те, чьи имена начинаются с точки . ) должны в большинстве, если не все, быть недоступны для других. Например: .htaccess , .htpasswd , .git , .hg .

Как вариант, вы можете показывать ошибку Not Found (не найдено), чтобы не давать атакующему подсказку:

Запретить доступ к файлам

Эти файлы могут быть оставлены некоторыми редакторами text/html (вроде Vi/Vim) и представляют огромную дыру в безопасности, если станут общедоступными.

Запретить листинг директорий

Запретить хотлинкинг изображений

Запретить хотлинкинг изображений для определенных доменов

Иногда вам потребуется запретить хотлинкинг только для некоторых доменов.

Защитить паролем директорию

Сначала нужно создать файл .htpasswd в определенной директории:

И потом использовать этот файл для аутентификации:

Защитить паролем один или несколько файлов

Заблокировать посетителя по Referrer

Блокирует доступ для всех пользователей, которые пришли (были перенаправлены) из определенного домена(-ов). Источник

Запретить рендеринг сайта во фрейме

Этот сниппет запрещает отображение сайта во фрейме (например, в теге iframe ), но разрешает отображение сайта во фрейме для определенных URI.

Сжатие текстовых файлов

Установить Expires Headers

Expires headers говорят браузеру, должен ли он загружать файл из сервера или же из кэша. Для статичного контента рекомендуется установить Expires заголовки на что-нибудь далекое в будущем.

Если вы не контролируете изменение версий с помощью перебора, основанного на файлах, подумайте о том, чтобы уменьшить время кэша для CSS и JS, например, до 1 недели. Источник

Удаляя заголовок ETag , вы выключаете кэш и избавляете возможности проверять браузером файлы, следовательно они будут полагаться на заголовки Cache-Control и Expires . Источник

Пользовательские страницы ошибок

Принудительная загрузка (скачивать файл вместо отображения в браузере)

Иногда нужно загрузить запрашиваемый файл, а не отображать его в браузере.

А ниже сниппет, который делает это с точностью до наоборот:

Запретить загрузку (отображать plain в браузере)

Иногда нужно отобразить запрашиваемый файл в браузере, а не загружать его.

Разрешить кроссдоменные шрифты

Шрифты, которые хранятся на CDN серверах, могут не работать в Firefox и IE из-за CORS. Данный сниппет решает эту проблему.

Установить по умолчанию кодировку UTF-8

Ваш текстовый контент должен быть всегда закодирован в UTF-8, не так ли?

Переключиться на другую версию PHP

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

Выключить просмотр в режиме совместимости в Internet Explorer

Просмотр в режиме совместимости в IE может оказать влияние на то, как отображаются некоторые сайты. Этот сниппет заставляет IE использовать движок Edge Rendering и выключает просмотр в режиме совместимости.

Обработка WebP изображений

У меня есть CSV-файл на моем сервере. Если пользователь нажимает на ссылку, он должен загрузиться, но вместо этого он открывается в окне моего браузера.

Мой код выглядит следующим образом:

<a href="files/csv/example/example.csv">

Нажмите здесь, чтобы загрузить пример файла CSV

</a>

Это обычный веб-сервер, на котором хранятся все мои разработки. Теперь содержимое моего файла csv.php:

header('Content-Type: application/csv');

header('Content-Disposition: attachment; filename=example.csv');

header('Pragma: no-cache');

Теперь моя проблема в том, что он загружает, но не мой CSV-файл. Он создает новый файл. Как решить данную проблему?

Ответ 1

.htaccess решение:

Чтобы перебрать все файлы CSV на вашем сервере для загрузки, добавьте в файл .htaccess:

AddType application/octet-stream csv

Решение PHP:

header('Content-Type: application/csv');

header('Content-Disposition: attachment; filename=example.csv');

header('Pragma: no-cache');

readfile("/path/to/yourfile.csv");

Ответ 2

Это невозможно сделать надежно, так как браузер должен решить, что делать с URL-адресом, который его попросили получить.

Вы можете сообщить браузеру сразу предложить «сохранить на диск», отправив заголовок Content-disposition:

header("Content-disposition: attachment");

Я не уверен, насколько хорошо это поддерживается различными браузерами. Альтернативой является отправка Content-type of application/octet-stream, но это хак (по сути, вы говорите браузеру : « Я не говорю тебе, что это за файл » , и в зависимости от того, что большинство браузеров затем предложит диалог загрузки) и, как утверждается, вызывает проблемы с Internet Explorer. Подробнее об этом читайте в FAQ по веб-авторингу.

Вы уже перешли на PHP-файл для доставки данных — это необходимо для установки заголовка Content-disposition (если только нет каких-то заумных настроек Apache, которые также могут это сделать). Теперь остается, чтобы этот PHP-файл прочитал содержимое CSV-файла — filename=example.csv , и в заголовке нужно указать браузеру, какое имя использовать для файла.

Ответ 3

Вот более безопасное для браузера решение:

$fp = @fopen($yourfile, 'rb');

if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))

header('Content-Type: "application/octet-stream"');

header('Content-Disposition: attachment; filename="yourname.file"');

header('Expires: 0');

header('Cache-Control: must-revalidate, post-check=0, pre-check=0');

header("Content-Transfer-Encoding: binary");

header('Pragma: public');

header("Content-Length: ".filesize($yourfile));

> else

header('Content-Type: "application/octet-stream"');

header('Content-Disposition: attachment; filename="yourname.file"');

header("Content-Transfer-Encoding: binary");

header('Expires: 0');

header('Pragma: no-cache');

header("Content-Length: ".filesize($yourfile));

>

fpassthru($fp);

fclose($fp);

Ответ 4

В п редыдущем ответе описывается, как использовать .htaccess для принудительной загрузки всех файлов определенного типа. Однако решение не работает со всеми типами файлов во всех браузерах. Вот более надежный способ:

<FilesMatch "\.(?i:csv)$">

ForceType application/octet-stream

Header set Content-Disposition attachment

</FilesMatch>

Возможно, вам придется очистить к э ш браузера, чтобы убедиться, что это работает правильно.

Ответ 5

Хорошее чистое решение:

<?php

header('Content-Type: application/download');

header('Content-Disposition: attachment; filename="example.csv"');

header("Content-Length: " . filesize("example.csv"));

$fp = fopen("example.csv", "r");

fpassthru($fp);

fclose($fp);

?>

Ответ 6

Если вы делаете это с самим приложением . Надеюсь, этот код поможет.

В href — вы должны добавить download_file.php вместе с вашим URL:

<a href="'/download_file.php?fileSource='+http://www.google.com/logo_small.jpg" target="_blank" title="YourTitle">

/* Здесь находится файл Download.php для принудительной загрузки */

<?php

$fullPath = $_GET['fileSource'];

if($fullPath)

$fsize = filesize($fullPath);

$path_parts = pathinfo($fullPath);

$ext = strtolower($path_parts["extension"]);

switch ($ext)

case "pdf":

header("Content-Disposition: attachment; filename=\"" . $path_parts["basename"]."\""); // Используйте 'attachment' для принудительной загрузки

header("Content-type: application/pdf"); // Добавьте сюда дополнительные заголовки для различных расширений.

break;

default;

header("Content-type: application/octet-stream");

header("Content-Disposition: filename=\"" . $path_parts["basename"]."\"");

>

if($fsize) < // Проверяем, существует ли размер файла

header("Content-length: $fsize");

>

readfile($fullPath);

exit;

>

?>

Ответ 7

  • X-SENDFILE изначально поддерживается

  • Apache требует модуль mod_xsend. В Ubuntu можно установить: apt install libapache2-mod-xsendfile

  • У Nginx похожий заголовок X-Accel Redirect

Мы будем очень благодарны

если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.

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