Безопасная загрузка файла в браузере с правильным именем файла - PullRequest
4 голосов
/ 19 декабря 2008

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

index.php? Страница = безопасная зона / загрузка и файл = protected.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: inline;» но это означает, что я не могу указать имя файла (потому что оно, похоже, игнорируется браузером). Проблема заключается в том, что когда я сохраняю документ, именем по умолчанию является URL-адрес, а не имя файла PDF-документа:

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

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

Ответы [ 5 ]

6 голосов
/ 24 декабря 2008

Я наконец нашел способ обойти эту проблему.

Хотя в RFC 2183 показано, что параметр имени файла можно использовать как для вложения, так и для строки в поле заголовка Content-Disposition, кажется, что браузеры игнорируют параметр имени файла при использовании 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:

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

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

// 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 преобразует пробелы в имени файла в + и одиночные кавычки в% 27 при сохранении (Firefox не делает), я бы хотел, чтобы это не происходило, но пока я доволен тем, что у меня есть есть.

1 голос
/ 19 декабря 2008

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

Content-Disposition: inline;
0 голосов
/ 07 октября 2009

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

0 голосов
/ 19 января 2009

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

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

0 голосов
/ 19 декабря 2008

Вы говорите это сделать, используя Content-disposition: attachment. Попробуйте использовать Content-disposition: inline.

...