Безопасно загрузите файл в браузере с правильным именем файла

StackOverflow https://stackoverflow.com/questions/381890

Вопрос

Я выполняю некоторую работу над веб-сайтом, на котором есть защищенная зона, доступная пользователям только после того, как они вошли в систему.В этой области есть страница со ссылками на PDF-документы, которые можно загрузить.Физические документы находятся за пределами корневого каталога веб-сайта.Ссылки на PDF-документы выглядят примерно так:

index.php?страница=безопасная зона/загрузитьифайл=защищенный.pdf

Который выполняет следующее (примечание:Я знаю, что это способ принудительной загрузки, а не открытия файла внутри браузер):

// check security, get filename from request, prefix document download directory and check for file existance then...

header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
header('Connection: Close');
set_time_limit(0);
readfile($file);

Это работает хорошо, но в Firefox 3 и Internet Explorer 7 (я не тестировал ни с каким другим браузером) этот файл не открывается внутри браузера, они оба показывают диалоговое окно загрузки (как и ожидалось).Если я выберу Открыть, а не Сохранить, документ будет загружен, и Adobe Reader запустится вне браузера для отображения документа.

Проблема, с которой я сталкиваюсь, заключается в загрузке файла внутри браузера и наличии правильного имени файла по умолчанию, если оно сохранено.

Я бы хотел, чтобы документ открылся в браузере.Одним из способов сделать это является использование заголовка "Content-Disposition:встроенный;" но это означает, что я не могу указать имя файла (потому что, похоже, оно игнорируется браузером).Проблема с этим заключается в том, что когда я сохраняю документ, по умолчанию используется имя URL, а не имя файла PDF-документа:

http___example.com_index.php_page=secure_area_download&file=protected.pdf

Как я могу заставить Firefox и Internet Explorer открыть документ внутри браузера и указать правильное имя файла по умолчанию для сохранения?

Это было полезно?

Решение

Наконец-то я придумал способ решения этой проблемы.

Хотя в RFC 2183 показано, что параметр filename может использоваться как для вложения, так и для встроенного поля заголовка Content-Disposition, похоже, что браузеры игнорируют параметр filename при использовании inline, а скорее пытаются определить, каким должно быть имя файла на основе URL.Если URL-адрес не содержит строки запроса, то в качестве имени файла, по-видимому, используется та часть URL-адреса, которая следует за последним /.

Я изменил ссылки, по которым загружаются защищенные документы PDF, на использование хороших URL-адресов, которые не содержат строки запроса, и использую mod_rewrite с файлом .htaccess для преобразования этих хороших URL-адресов для выполнения правильного скрипта с правильными параметрами:

Старая ссылка:

index.php?page=secure-area/download&file=document.pdf

Новая Ссылка:

file/secure-area/download/document.pdf 

.htaccess .htaccess:

RewriteEngine On
RewriteRule ^file/secure-area/download/(.*)$ index.php?page=secure-area/download&file=$1 [L]

Скрипт, используемый для фактической отправки файла, такой же, как я использовал ранее (обратите внимание, что в примере в вопросе используется Content-Disposition:привязанность, а не Расположение контента:встроенный для демонстрации браузерам сохранения документа с правильным именем файла при не встроенный).

// check security, get filename from request, prefix document download directory and check for file existance then...
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="' . basename($file) . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
header('Connection: Close');
set_time_limit(0);
readfile($file);

Теперь PDF-документ открывается в браузере, и при сохранении имя файла по умолчанию равно

document.pdf

и не

http___example.com_index.php_page=secure_area_download&file=document.pdf

IE 7 преобразует пробелы в имени файла в + 's и одинарные кавычки в %27 при сохранении (Firefox этого не делает), я бы хотел, чтобы этого не происходило, но пока я доволен тем, что у меня есть.

Другие советы

Попробуйте использовать

Content-Disposition: inline;

Нет, она говорит о том, что невозможно указать имя файла, когда используется 'Content-disposition:inline'.'Filename' используется только при использовании 'Content-disposition:attachment', как в ее первом примере.В результате документ загружается с правильным именем файла.Однако то, чего пытается достичь это решение, - это документ, отображаемый встроенным образом, который при загрузке из браузера использует правильное имя файла вместо имени скрипта.

Есть ли какой-либо другой способ указать имя файла при использовании 'inline', отличный от перезаписи URL?Страница, которую я написал для рендеринга документов, принимает идентификатор базы данных, поэтому, я думаю, переписать было бы сложнее (имя файла пришлось бы запрашивать из базы данных).

Content-disposition:inline может использоваться с именем файла.Но только некоторые браузеры понимают это и следуют этому.Эффект виден только тогда, когда вы сами сохраняете имя файла, будет использоваться имя файла, которое вы определяете с помощью content disposition.

Вы говорите ему сделать это, используя Content-disposition:привязанность.Попробуйте использовать Content-disposition (Расположение содержимого):встроенный.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top