IHttpAsyncHandlerを継承するWebHandlerを使用する場合、特定の状況が不明な場合、ブラウザーMS IE6がそれを表示せず、要求が終了しないことに気付かないはずです。修正はありますか?
2 に答える
自分で答えますが、この問題に最初に遭遇したとき、私はそれを解決するのに3日かかりました。
「img」HTMLタグの「src」プロパティを介して画像がリクエストされた場合、特定の条件では、ブラウザMSIE6はリクエストを終了して結果を表示するためにContent-Lengthを必要とします。
同期ASHXで生成された画像には、自動的に「Content-Length」HTTPヘッダーが含まれますが、非同期バージョンには含まれません。したがって、出力を書き込むときは、最初にメモリストリームに書き込み、全長を読み取り、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);
}
}
コードの同期バージョンと非同期バージョンの両方をtcpdumpしましたが、それらの間にさらに2つの違いがあることに気付きました。
1)非同期ハンドラーは、回答を1つではなく3つのTCPパケットに分割します。
2)同期バージョンは別の「Keep-Alive」ヘッダーを使用します(どれを思い出せません)
HTTP 仕様は、クライアントがリクエストの長さを決定する方法を概説しています (特に content-length が使用されていない場合)。コンテンツ長ヘッダーが存在せず、応答がチャンク化されていない場合、IIRC は、接続が閉じられるまでに要求の終わりが検出されます (これは、キープアライブ動作が変更された理由を示している可能性があります。keep は使用できません)。 -alive (要求の長さを示すために接続の存続期間が使用される場合)。ただし、ASP.NET がこれを自動的に処理することを期待しています。おそらく、ASP.NET に応答が完了したことを伝える呼び出しが見逃されている可能性があります。
非同期になる前に content-length ヘッダーを追加できるようにコンテンツ全体を生成すると、そもそも非同期 HttpHandler を使用する目的が無効になるようです。