Вопрос

Я транслирую 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
  Cache-Control: 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: двоичное " а также «приложение / принудительная загрузка»; для ContentType. Пока ничего не помогло. Существует несколько Microsoft КБ article , все из которых указывают на то, что Cache-Control: no-cache является виновником. Есть другие идеи?

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

Обновление: прогресс достигнут не был. Я послал по электронной почте файл .SAZ

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

Решение 2

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

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

  
    
      

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

             

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

             

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

    
  

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

  
    
      

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

             

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

    
  

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

Ваш заголовок 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 подробнее об этой теме.

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

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

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

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

ATT: Mr.Dark

Мы уже давно сталкивались с подобной проблемой - то, что мы сделали, - это мы (это 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"

Какая версия IE? Напоминаю, что Microsoft выпустила исправление для IE6 для этой проблемы. Надеюсь, что это полезно?

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

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

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

Вот мой код

    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();

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

            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);
            }

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

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

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

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