Почему асинхронные изображения, созданные в ASHX, не всегда работают в IE6? - PullRequest
3 голосов
/ 23 декабря 2008

Если вы используете WebHandler, унаследованный от IHttpAsyncHandler, вы не должны замечать, что при неопределенных конкретных обстоятельствах браузер MS IE6 не будет отображать его, запрос никогда не завершится. Есть ли исправление для этого?

Ответы [ 2 ]

4 голосов
/ 23 декабря 2008

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

Когда изображение запрашивается через свойство «src» HTML-тега «img», в определенных условиях браузеру MS IE6 требуется Content-Length для завершения запроса и отображения результата.

Синхронные изображения, сгенерированные ASHX, автоматически включают HTTP-заголовок «Content-Length», а асинхронная версия - нет. Поэтому, когда вы записываете вывод, сначала запишите его в поток памяти, прочитайте общую длину, запишите его как заголовок HTTP, а затем запишите поток вывода в вывод.

Как это:

using (Image resizedImage = generateImage())
{
    using (MemoryStream memoryStream = new MemoryStream())
    {
        resizedImage.Save(memoryStream, ImageFormat.Jpeg);
        context.Response.AddHeader("Content-Length", memoryStream.Length.ToString());
        memoryStream.WriteTo(context.Response.OutputStream);
    }
}

Я tcpdumped Синхронная и Асинхронная версии моего кода, и я заметил еще 2 различия между ними:

1) Асинхронный обработчик делит ответ на 3 TCP-пакета вместо одного.

2) Синхронная версия использует другой заголовок "Keep-Alive" (я не помню, какой именно)

1 голос
/ 31 декабря 2008

Спецификация HTTP описывает, как клиент должен определять длину запроса (в частности, когда длина содержимого не используется). IIRC, если заголовок длины содержимого отсутствует, а ответ не разделен на части, то конец запроса обнаруживается при закрытии соединения (что может указывать на то, почему было изменено поведение keep-alive - нельзя использовать keep -alive, если время жизни соединения используется для указания длины запроса). Я ожидаю, что ASP.NET позаботится об этом автоматически, хотя. Возможно, отсутствует какой-то вызов, который сообщает ASP.NET, что ответ завершен.

Кажется, что генерация всего контента, чтобы вы могли добавить заголовок длины контента перед переходом в асинхронный режим, в первую очередь сводит на нет цель использования асинхронного HttpHandler.

...