У меня есть (виртуальный) сервер 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, но вам нужно быть осторожным, чтобы гарантировать, что ответ действительно будет сжат, что может быть не для всех типов содержимого.