Загрузка файлов в IE6 - PullRequest
       18

Загрузка файлов в IE6

3 голосов
/ 08 сентября 2008

Я столкнулся с довольно интересной (и разочаровывающей) проблемой с IE6. Мы обслуживаем некоторые сгенерированные сервером pdf и затем просто устанавливаем заголовки в PHP, чтобы принудительно загрузить файл из браузера. Работает нормально и все, кроме IE6, но только , если учетная запись пользователя Windows установлена ​​на обычного пользователя (то есть, не администратора).

Поскольку это для корпоративной среды, конечно, все их учетные записи настроены таким образом. Странно то, что в диалоге загрузки Content-Type не распознается:

header( 'Pragma: public' );
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate, pre-check=0, post-check=0' );
header( 'Cache-Control: public' );
header( 'Content-Description: File Transfer' );
header( 'Content-Type: application/pdf' );
header( 'Content-Disposition: attachment; filename="xxx.pdf"' );
header( 'Content-Transfer-Encoding: binary' );
echo $content;
exit;

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

Ответы [ 10 ]

4 голосов
/ 08 апреля 2009

Эти заголовки являются поддельными!

Content-Transfer-Encoding: binary

Этот заголовок скопирован из заголовков электронной почты. Это не относится к HTTP просто потому, что в HTTP нет другого способа передачи, кроме двоичного. Установка имеет такой же смысл, как и установка X-Bits-Per-Byte: 8.

Cache-control: pre-check=0, post-check=0

Эти нестандартные значения определяют, когда IE должен проверять, является ли кэшированное содержимое свежим. 0 является значением по умолчанию, поэтому установка его на 0 - пустая трата времени. Эти директивы применяются только к кешируемому контенту, и Expires:0 и must-revalidate подсказывают, что вы хотели сделать его не кешируемым.

Content-Description: File Transfer

Это еще один подражатель электронной почты. По умолчанию этот заголовок никак не влияет на загрузку . Это просто информативный текст в свободной форме. Технически он так же полезен, как заголовок X-Hi-Mom: I'm sending you a file!.

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

В PHP вторая строка полностью перезаписывает первую. Вы, кажется, наносите удар в темноте.

Что действительно имеет значение

Content-Disposition: attachment

Вам не нужно вставлять туда имя файла (вы можете использовать трюк mod_rewrite или index.php/fakefilename.doc - он дает гораздо лучшую поддержку специальных символов и работает в браузерах, которые игнорируют необязательный Content-Disposition заголовок).

В IE не имеет значения, находится ли файл в кеше или нет («Открыть» не работает для файлов, которые не кэшируются), и есть ли у пользователя плагин, который утверждает, что поддерживает тип файла, который обнаруживает IE.

Чтобы отключить кеш, вам нужно всего лишь Cache-control:no-cache (без 20 дополнительных фальшивых заголовков), а чтобы сделать файл кэшируемым, вам не нужно ничего отправлять.

Примечание: PHP имеет ужасную ошибку, называемую session.cache_limiter, которая безнадежно портит заголовки HTTP, если вы не установите его в none.

ini_set('session.cache_limiter','none'); // tell PHP to stop screwing up HTTP
3 голосов
/ 08 сентября 2008

некоторые версии IE, кажется, занимают

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

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

Удалите эти два, и все будет в порядке.

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

Я знаю, что здесь я расплывчато, но приведенные выше советы основаны на реальном опыте, который я получил, используя веб-приложение, обслуживающее динамически создаваемые PDF-файлы, содержащие штрих-коды. Я не знаю, какие версии подвержены уязвимости, я только знаю, что использование двух «уловок», приведенных выше, привело к исчезновению обращений в службу поддержки: p

1 голос
/ 20 апреля 2011

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

public function download(sfResponse $response) {

        $response->clearHttpHeaders();
        $response->setHttpHeader('Pragma: public', true);
        $response->addCacheControlHttpHeader("Cache-control","private");        
        $response->setContentType('application/octet-stream', true);
        $response->setHttpHeader('Content-Length', filesize(sfConfig::get('sf_web_dir') .       sfConfig::get('app_paths_docPdf') . $this->getFilename()), true);
        $response->setHttpHeader("Content-Disposition", "attachment; filename=\"". $this->getFilename() ."\"");
        $response->setHttpHeader('Content-Transfer-Encoding', 'binary', true);
        $response->setHttpHeader("Content-Description","File Transfer");
        $response->sendHttpHeaders();
        $response->setContent(readfile(sfConfig::get('sf_web_dir') . sfConfig::get('app_paths_docPdf') . $this->getFilename()));

        return sfView::NONE;
}

Это прекрасно работает в IE6, IE7, Chrome, Firefox.

Надеюсь, это кому-нибудь поможет.

1 голос
/ 08 сентября 2008

У меня была точно такая же проблема около года назад, и после долгих поисков и поисков, мои заголовки (из кода Java) выглядят так: IE6 и PDF:

    response.setHeader("Content-Type", "application/pdf "; name=" + file.getName());
    response.setContentType("application/pdf");
    response.setHeader("Last-Modified", getHeaderDate(file.getFile());
    response.setHeader("Content-Length", file.getLength());

Отбрось все остальное.

Похоже, что-то не так с IE6, кешированием, принудительной загрузкой и плагинами. Я надеюсь, что это работает для вас ... небольшая разница для меня заключается в том, что запрос изначально приходит из Flash SWF-файла. Но это не должно иметь значения.

0 голосов
/ 21 сентября 2010

просто переключитесь на этот тип контента, и он будет работать, также убедитесь, что Pragma is is установлено на что-то НЕ равное "no-cache"

header( 'Content-type: application/octet-stream'); # force download, no matter what mimetype
header( 'Content-Transfer-Encoding: binary' ); # is always ok, also for plain text
0 голосов
/ 03 февраля 2010

Если вы используете SSL:

Убедитесь, что вы не включили заголовки элемента управления кэшем (или Pragma). В IE6 есть ошибка, которая не позволяет пользователям загружать файлы, если используются заголовки управления кэшем. Они получат сообщение об ошибке.

Я выдернул волосы в течение 2 дней, так что, надеюсь, это сообщение кому-нибудь поможет.

0 голосов
/ 28 июля 2009

У меня была похожая проблема, но она может быть не совсем связана. Моя проблема заключалась в том, что IE6, похоже, имеет проблему со специальными символами (в частности, косыми чертами) в имени файла. Удаление этих исправило проблему.

0 голосов
/ 25 сентября 2008

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

http://www.mycom.com/services/pdf?action=blahblah&filename=pdf0001.pdf

Я сталкивался со случаями, когда ie будет с большей вероятностью читать имя файла в конце URL, чем любой из заголовков

0 голосов
/ 25 сентября 2008

У меня работает следующий фрагмент кода Java (проверено на Firefox 2 и 3, IE 6 и 7):

response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
response.setContentType(getServletContext().getMimeType(file.getName()));
response.setContentLength(file.length());

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

0 голосов
/ 16 сентября 2008

Как уже упоминалось в pilif, обязательно отключите сжатие gzip на стороне сервера. Для меня это вызвало проблемы с PDF-файлами (среди прочих типов), а также, возможно, не очень неясными причинами, а также с .zip-файлами как в Internet Explorer, так и в FireFox.

Насколько я могу судить, последний бит нижнего колонтитула zip будет удален (по крайней мере, из-за FireFox), что приведет к повреждению формата.

В PHP вы можете использовать следующий код:

ini_set("zlib.output_compression",0);
...