Генерация PDF, ошибка с IE и HTTPS - PullRequest
12 голосов
/ 29 июля 2009

Я транслирую PDF в браузер в ASP.NET 2.0. Это работает во всех браузерах по HTTP и во всех браузерах , кроме IE по HTTPS. Насколько я знаю, это работало (последние 5 лет или около того) во всех версиях IE, но наши клиенты только недавно начали сообщать о проблемах. Я подозреваю, что опция безопасности Не сохранять зашифрованные страницы на диск раньше была отключена по умолчанию и в какой-то момент стала включена по умолчанию (Свойства обозревателя -> Дополнительно -> Безопасность). Отключение этой опции помогает в качестве обходного пути, но не является жизнеспособным в качестве долгосрочного решения.

Я получаю сообщение об ошибке:

Internet Explorer не может загрузить файл OutputReport.aspx с веб-сайта www.sitename.com.

Internet Explorer не смог открыть этот интернет-сайт. Запрашиваемый сайт либо недоступен, либо не найден. Пожалуйста, попробуйте позже.

Инструментом, используемым для создания PDF, является ActiveReports из DataDynamics . После того, как PDF создан, вот код для его отправки:

Response.ClearContent()
Response.ClearHeaders()
Response.AddHeader("cache-control", "max-age=1")
Response.ContentType = "application/pdf"
Response.AddHeader("content-disposition", "attachment; filename=statement.pdf")
Response.AddHeader("content-length", mem_stream.Length.ToString)
Response.BinaryWrite(mem_stream.ToArray())
Response.Flush()
Response.End()  

Примечание. Если я не укажу явно управление кэшем, тогда .NET отправляет no-cache от моего имени, поэтому я попытался установить управление кэшированием: private или public или maxage = #, но, похоже, ни один из них работа.

Вот поворот: когда я запускаю Fiddler для проверки заголовков ответов, все работает нормально. Заголовки, которые я получаю:

HTTP / 1.1 200 OK
Контроль кэша: max-age = 1
Дата: среда, 29 июля 2009 г. 17:57:58 GMT
Тип контента: приложение / pdf
Сервер: Microsoft-IIS / 6.0
MicrosoftOfficeWebServer: 5.0_Pub
X-Powered-By: ASP.NET
X-AspNet-версия: 2.0.50727
содержание-расположение: вложение; имя_файла = Statement.pdf
Контент-кодировка: gzip
Варьируется: Accept-Encoding
Передача-кодировка: чанкованная

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

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

Обновление: Проблемы с Fiddler решены, большое спасибо EricLaw, поэтому теперь он ведет себя согласованно (не работает, работает или нет Fiddler).

По результатам поиска в Google, по всей видимости, существует множество сообщений об этой же проблеме по всему Интернету, каждый из которых имеет свою собственную конкретную комбинацию заголовков ответов, которые, похоже, решают проблему в отдельных случаях. Я попробовал многие из этих предложений, включая добавление ETag, дату LastModified, удаление заголовка Vary (с помощью Fiddler) и десятки комбинаций заголовков Cache-Control и / или Pragma. Я попробовал «Content-Transfer-Encoding: binary», а также «application / force-download» для ContentType. Пока ничего не помогло. Есть несколько Microsoft KB статей , все из которых указывают, что Cache-Control: no-cache виновник Есть еще идеи?

Обновление: Кстати, для полноты, такая же проблема возникает и с выходами Excel и Word.

Обновление: Нет прогресса. Я послал по электронной почте файл .SAZ из Fiddler в EricLaw, и он смог воспроизвести проблему при отладке IE, но пока нет решений. Щедрость истекает ...

Ответы [ 12 ]

3 голосов
/ 30 июля 2009

Ваш заголовок Cache-Control неверен. Это должно быть Cache-Control: max-age = 1 с чертой в середине. Попробуйте исправить это в первую очередь, чтобы увидеть, если это имеет значение.

Как правило, я бы сказал, что наиболее вероятным виновником является ваш заголовок Vary, поскольку такие заголовки часто вызывают проблемы с кэшированием в IE: http://blogs.msdn.com/ieinternals/archive/2009/06/17/9769915.aspx. Возможно, вы захотите попробовать добавить ETAG в заголовки ответа.

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

> Не сохранять зашифрованные страницы на диске, параметр безопасности, который по умолчанию отключен

Эта опция по умолчанию по-прежнему отключена (в IE6, 7 и 8), хотя ИТ-администраторы могут включить ее через групповую политику, и некоторые крупные компании делают это.

Кстати, причина, по которой вы видите ошибку сертификата при запуске Fiddler, заключается в том, что вы не решили доверять корневому сертификату Fiddler; см. http://www.fiddler2.com/fiddler/help/httpsdecryption.asp для получения дополнительной информации по этой теме.

2 голосов
/ 17 января 2011

У меня была похожая проблема с файлами PDF, которые я хотел транслировать. Даже с Response.ClearHeaders() я видел заголовки Pragma и Cache-Control, добавленные во время выполнения. Решением было очистить заголовки в IIS (щелкните правой кнопкой мыши -> Свойства на странице загрузки PDF, затем вкладка «Заголовки Http»).

2 голосов
/ 11 августа 2009

После двух недель в погоне за диким гусем я не смог найти никакой комбинации изменений кода, которая позволила бы этот метод потоковой передачи документов PDF, Excel или Word, когда ' Не сохраняет зашифрованные страницы на диск 'опция включена.

Microsoft заявляет, что такое поведение предусмотрено в ряде статей по КБ и в частных электронных письмах. Похоже, что когда включена опция « Не сохранять зашифрованные страницы на диск », IE ведет себя правильно и выполняет то, что ему говорят. Этот пост - лучший ресурс, который я нашел на данный момент, объясняющий, почему этот параметр будет включен, и плюсы и минусы его включения:

" Не сохранять зашифрованные страницы на диск " вступает в игру при работе с соединениями SSL (HTTPS). Так же, как веб-сервер может отправлять готовую информацию о том, как кэшировать файл, можно в принципе настройте Internet Explorer так, чтобы файлы не сохранялись в кэш во время соединения SSL (HTTPS), независимо от того, рекомендует ли веб-сервер это сделать.

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

В чем недостаток? Низкая производительность, поскольку в кэш ничего не сохраняется, даже если 1-байтовое gif-изображение, которое использовалось на странице десяток раз, необходимо каждый раз получать с веб-сервера. Что еще хуже, некоторые пользовательские действия могут завершиться сбоем, например, загруженные файлы будут удалены, а при появлении ошибки или открытии документов PDF не будет названо несколько сценариев. "

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

«Использовать« Пустую папку временных файлов Интернета, когда браузер закрыт ». Каждый раз, когда браузер закрывается, все файлы будут удаляться из кэша, при условии, что нет блокировки файла из другого экземпляра браузера или какого-либо внешнего приложения.

Прежде чем использовать ', необходимо уделить много внимания не сохранять зашифрованные страницы на диск '. Похоже, это отличная функция безопасности, но результаты использования этой функции могут привести к увеличению числа обращений в службу поддержки из-за сбоев загрузки или низкой производительности. "

1 голос
/ 18 мая 2011

решено: это проблема IE, а не из приложения ... исправить это с помощью: http://support.microsoft.com/kb/323308 Это идеально подходит для меня, после попытки в течение длительного времени.

ATT: Мистер Дарк

1 голос
/ 16 июля 2010

Я обнаружил, что это, кажется, работает для меня:

Dim browser As System.Web.HttpBrowserCapabilities = Request.Browser
If (browser.Browser = "IE") Then
  Response.AppendHeader("cache-control", "private") ' ie only
Else
  Response.AppendHeader("cache-control", "no-cache") ' all others (FF/Chrome tested)
End If
1 голос
/ 11 августа 2009

Мы уже давно сталкивались с подобной проблемой - то, что мы сделали, - это мы (это Java EE). В конфиге веб-приложения добавляем

<mime-mapping>
    <extension>PDF</extension>
    <mime-type>application/octet-stream</mime-type>
</mime-mapping>

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

РЕДАКТИРОВАТЬ : похоже, вы транслируете его. В этом случае вы будете использовать mime-тип в качестве application / octet-stream в вашем коде, а не в конфигурации. Так вот вместо

Response.ContentType = "application/pdf"

вы будете использовать

Response.ContentType = "application/octet-stream"
0 голосов
/ 17 апреля 2015

Я столкнулся с подобной проблемой при попытке потоковой передачи PDF через SSL и помещения ее в iframe или объект. Я обнаружил, что моя страница aspx будет продолжать перенаправлять на незащищенную версию URL, и браузер будет блокировать ее.

Я обнаружил, что переключение со страницы ASPX на обработчик ASHX устранило мою проблему с перенаправлением.

0 голосов
/ 06 марта 2015

Как и ОП, я несколько дней чесал голову, пытаясь заставить это работать, но в конце концов я сделал это, поэтому решил поделиться своей «комбинацией» заголовков:

            if (System.Web.HttpContext.Current.Request.Browser.Browser == "InternetExplorer"
                && System.Web.HttpContext.Current.Request.Browser.Version == "8.0")
            {
                System.Web.HttpContext.Current.Response.Clear();
                System.Web.HttpContext.Current.Response.ClearContent();
                System.Web.HttpContext.Current.Response.ClearHeaders();
                System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream";

                System.Web.HttpContext.Current.Response.AppendHeader("Pragma", "public");
                System.Web.HttpContext.Current.Response.AppendHeader("Cache-Control", "private, max-age=60");
                System.Web.HttpContext.Current.Response.AppendHeader("Content-Transfer-Encoding", "binary");

                System.Web.HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=" + document.Filename);
                System.Web.HttpContext.Current.Response.AddHeader("content-length", document.Data.LongLength.ToString());

                System.Web.HttpContext.Current.Response.BinaryWrite(document.Data);
            }

Надеюсь, это спасет кого-то от боли!

0 голосов
/ 08 февраля 2012

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

Вот мой код

    byte[] bytes = // get byte array from DB

    Response.Clear();
    Response.ClearContent();
    Response.ClearHeaders();
    Response.Buffer = true;

    // Prevent this page from being cached.
    //  NOTE: we cannot use the CacheControl property, or set the PRAGMA header value due to a flaw re: PDF/SSL/IE
    Response.Expires = -1; 

    Response.ContentType = "application/pdf";
    // Specify the number of bytes to be sent
    Response.AppendHeader("content-length", bytes.Length.ToString());

    Response.BinaryWrite(bytes);    

            // Wrap Up
    Response.Flush();
    Response.Close();
    Response.End();
0 голосов
/ 11 августа 2009

попробуйте отключить сжатие gzip.

...