Назад | Перейти на главную страницу

Загрузка PDF зависает с сервера с Firefox / Chrome

У меня есть (виртуальный) сервер Windows 2008 R2, на котором работает несколько веб-сайтов. Мой клиент загрузил несколько PDF-файлов по FTP в каталог для загрузки, откуда их можно получить через веб-страницу.

Это отлично работает в IE и Safari, но при попытке загрузки с помощью Firefox или Chrome оба браузера зависают, и Firefox сообщает «остановлен» в строке состояния внизу страницы. Мы пробовали это на нескольких компьютерах в разных местах, поэтому я думаю, что это может быть проблема с сервером - хотя, возможно, программное обеспечение, используемое для создания PDF-файлов, могло создать что-то несовместимое с потоковой передачей в Firefox / Chrome.

Почему могут быть причины для такого поведения? Есть ли какие-то параметры конфигурации, которые мне нужно изменить?

РЕДАКТИРОВАТЬ: проверенные заголовки с помощью Firebug - GET придерживается 206 частичного содержимого

Content-Type    application/pdf
Last-Modified   Sun, 21 Mar 2010 19:50:49 GMT
Accept-Ranges   bytes
Etag    "42da4bce2fc9ca1:0"
Server  Microsoft-IIS/7.5
X-Powered-By    ASP.NET
Date    Thu, 27 May 2010 15:39:34 GMT
Content-Length  329532
Content-Range   bytes 27484-357015/357016
Request Headersview source
Host    www.caepost.co.uk
User-Agent  Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
Accept  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language en-gb,en;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive  115
Connection  keep-alive
Range   bytes=27484-357015,27484-27485

IIS версии 7.5 изменил способ ответа на запросы байтового диапазона, например, сделанные подключаемым модулем Acrobat. Если запрос относится к одному непрерывному диапазону, IIS теперь отвечает заголовком «Content-Range», а не заголовком «ContentType: multipart / byteranges», который на самом деле является допустимым HTTP, но вводит в заблуждение подключаемый модуль Acrobat.

Adobe в настоящее время работает над исправлением: http://kb2.adobe.com/cps/807/cpsid_80780.html

А тем временем Microsoft предоставила исправление, чтобы вернуть IIS 7.5 к старому поведению: http://support.microsoft.com/kb/979543

Мы обновили серверы, и IIS 7.5 дал нам ту же проблему. Проверил заголовки и подтвердил проблему.

Применил исправление http://support.microsoft.com/kb/979543 но это не решило проблему. Думаю, разница здесь в том, что наш сайт работал в классическом режиме. (Пришлось сделать это для установленного другого продукта (Imis)). Таким образом, исправление работает только в том случае, если ваш сайт работает в интегрированном режиме.

В конце концов, мне пришлось написать обработчик для перехвата запросов PDF-документов и изменения заголовка ответа.

context.Response.ContentType = "application/pdf";
context.Response.TransmitFile(filePath);
context.Response.End();

Это сработало.

Системные операции не ограничивались открытием документов Acrobat. В нашем случае Google Chrome также зависал, когда пытался открыть PDF-файл, независимо от того, какая у вас программа для чтения PDF-файлов.

Можете ли вы опубликовать отправленные заголовки ответов?

Панель Firebug Net:

(источник: getfirebug.com)

Просмотр заголовков:

(источник: getfirebug.com)

Это могло быть связано с настройками сжатия в IIS 7.0.

Заголовок запроса содержит следующее:

Accept-Encoding: gzip,deflate

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

Когда вы используете:

context.Response.TransmitFile(filePath);

IIS проверяет установленный тип содержимого и решает, нужно ли сжимать ответ.

К сожалению, IIS не добавляет

Content-Encoding: gzip

в заголовок ответа, что означает, что Firefox и Chrome не могут определить, сжаты ли данные или нет.

Отключение сжатия содержимого в IIS должно исправить это, но повлияет на весь веб-сайт. Также в некоторых случаях может сработать предложение установить тип содержимого. IIS 7 решает, нужно ли сжимать ответ на основе mime-типа.

http://www.iis.net/configreference/system.webserver/httpcompression дает следующий пример настройки httpCompression в файле ApplicationHost.config:

<httpCompression
      directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
   <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
   <dynamicTypes>
      <add mimeType="text/*" enabled="true" />
      <add mimeType="message/*" enabled="true" />
      <add mimeType="application/javascript" enabled="true" />
      <add mimeType="*/*" enabled="false" />
   </dynamicTypes>
   <staticTypes>
      <add mimeType="text/*" enabled="true" />
      <add mimeType="message/*" enabled="true" />
      <add mimeType="application/javascript" enabled="true" />
      <add mimeType="*/*" enabled="false" />
   </staticTypes>
</httpCompression>

Другой вариант - убедиться, что Content-Encoding: gzip всегда добавляется в заголовок Response, но вам нужно быть осторожным, чтобы гарантировать, что ответ действительно будет сжат, что может быть не для всех типов содержимого.