再度text/vnd.wap.wmlによるASP.NET OutputCache Bugおよび解決方法

11255 ワード

前の記事「ASP.NETを伴う1.0から4.0までのOutputCache Bug」で、ASP.NET OutputCacheのブラウザキャッシュのBug.
この文章では、ASPを暴露します.NET OutputCacheのもう一つのBugは、このBugが昨年2月に一度暴露されたことがあるが、当時は徹底的に暴露されず、解決策も完璧ではなかった.ここでもう一度暴露します.
背景紹介
非電信ユーザーがブログパークにアクセスするネット速度の問題(特に北方ネット通ユーザー)を解決するために、CDN加速を採用する予定です.CDNを加速させるには、有効なページキャッシュメカニズムを確立します(OutputCache Locationは「Any」に設定します).この実用的な応用問題を解決するためには、ASPをよく研究しなければならない.NET OutputCacheなので、そのBugを暴露します.
重要なヒント
ASPにいたらNETアプリ(非ASP.NET MVC)でOutputCacheを使用しているので、このBugに注目して、必ず手を出して解決してください!
もんだいげんしょう
もしあなたが上の姿を見たことがあるならば、あなたはかつてこのBugと出会ったことがあってあるいは再会したことがあります.△何気ない出会いや再会は、肩をこすっただけかもしれないし、永遠かもしれない.偶然を期待しないで、偶然を無視しないでください.
当初、私たちが出会ったとき、それは「ぼんやり」していて(あまり見られない特定の状況に現れた)、人を「うっとりさせた」(この問題に直面して手がつけられない).
ブラウザはなぜこのウィンドウを提供しますか?
Webサーバとブラウザが「Content-Type:text/vnd.wap.wml;charset=utf-8」と一言言ったからだ.どうしてそんなことを言うの?次の分解を見てください.
問題発生プロセス
1)ASPにいるときNETページにOutputCacheの設定が追加されました.たとえば、次のようになります.
 
  

2)然后,在缓存没有建立(或者已经过期)时,一部手机通过浏览器以WAP方式第一个请求了这个页面(Request headers中包含"Accept:text/vnd.wap.wml",这样的请求可能通过代码进行模拟,详见这里)。

3)接着,ASP.NET将这个请求的响应缓存了起来。这个操作是在System.Web.Caching.OutputCacheModule.OnLeave中进行的,缓存内容来自System.Web.HttpResponse.GetSnapshot(),不仅缓存了Response body,而且缓存了Response headers。

*【关键地方】在缓存Response headers时,ASP.NET根据"C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\Browsers\Default.browser"中的配置进行了特殊处理:

<defaultBrowser id="Wml" parentID="Default">
<identification>
<header name="Accept" match="text/vnd\.wap\.wml|text/hdml"/>
<header name="Accept" nonMatch="application/xhtml\+xml; profile|application/vnd\.wap\.xhtml\+xml"/>
identification>
<capabilities>
<capability name="preferredRenderingMime"              value="text/vnd.wap.wml"/>
<capability name="preferredRenderingType"              value="wml11"/>
capabilities>
defaultBrowser>

要求を開始するAcceptがtext/vndであるため.wap.wmlなので、上のはちょうど一致して、それからASP.NETは、ここでの構成に従って、Response headersにおけるContent-Typeの変更を「text/vnd.wap.wml;charset=utf-8」としてキャッシュします.
4)次のキャッシュサイクル中の要求はすべてこのキャッシュによって迎えられ(操作はSystem.Web.Caching.OutputCacheModule.OnEnterで行われ、最終的にSystem.Web.HttpResponse.UseSnapshotによってキャッシュ内容が返される)、WAP方式の要求でない限り、上図のダウンロードファイルダイアログボックスが表示される.
この問題を解決しようとしたとき、私たちはこの応答をキャプチャしようとしたが、FireFoxのFirebug、ChromeのDeveloper tools、Fiddlerでは捉えられず、後になってIE 9のDeveloper toolsを試してみたところ、意外にも捉えられた(IE 9によるサプライズを初めて楽しむ).次の図を参照してください.
問題の原因はここにあり、正しいContent-Typeは「text/html;charset=utf-8」、ASP.NETはWAPリクエストに特化し、AcceptがContent-Typeを決定する(「お尻が頭を決める」のか).WAPのアプリケーションシーンではこのようなデザインが必要かもしれませんが、OutputCacheへの影響は考慮されていません.
(注:クライアント要求のAcceptをtext/plainなどの他のタイプに変更しても、この問題はありません)
前に述べた過程から、問題を解決するには第3ステップで述べたDefaultを知ることができる.browserファイルを手に入れます.
推奨ソリューション
前提条件:現在のWebサーバにWAPサイトがない
利点:現在のWebサーバ上のすべてのサイトに有効な変更.
操作手順:
  • C:WindowsMicrosoft.NET\Framework\v4.0.30319\Config\Browsers
  • Default.browserファイルをデスクトップにコピー(別のフォルダにコピーしてバックアップ)
  • 好きな編集でデスクトップのDefaultを開く.browserファイル、セクション、コメント、または***以下の構成を見つけて保存します.
  • <capabilities>
    <capability name="preferredRenderingMime"              value="text/vnd.wap.wml"/>
    <capability name="preferredRenderingType"              value="wml11"/>
    capabilities>
  • 修正したDefault.browserファイルは「C:WindowsMicrosoft.NETFrameworkv 4.0.30319ConfigBrowsers」にコピーし、同名ファイルを上書きします.
  • 管理者としてコマンドラインを実行し、cdは「C:WindowsMicrosoft.NETFrameworkv 4.0.30319」に入り、コマンド「aspnet_regbrowsers-i」を実行する:
  • 大功により、OutputCacheを存分に行うことができる.

  • 注:この解決方法は以前の経験に基づく——ASP.NET 4ではRequestを信用しないでください.Browser.Cookies,Form検証はUseCookiesを使いますが,当時ブログを書かなければ,この解決策を見つけるのはそんなに簡単ではありません.
    原因が分かりました.解決方法はいろいろありますが、ここでは私たちが採用する解決方法だけをリストします.
    ASP.NET MVCは?
    ASP.NET MVCにはこのBugはありませんが、前述の「ブラウザキャッシュのBug」はASP.NET MVCにも存在しない.
    小結
    1)なぜASP.NETにはこれらのBugがあり、ASP.NET MVCはありませんか?
    その一つの重要な原因はASPだと思います.NETの閉鎖、ASP.NET MVCのオープン(オープンソース)--ソースコードがあれば、開発者が問題を発見したときに本当の原因をより速く見つけ、マイクロソフトにフィードバックすることができます.マイクロソフトがすぐに問題を解決できなくても、少なくとも私はソースコードを修正して自分で問題を解決することができます.この条件があれば、開発者は問題に直面してやっと真相を究明したいと思っています.そうでなければ、問題の原因が見つかったとしても、ソースコードを修正できないため、問題に嘆くしかありません(例えば、私が前に出会ったEntity Frameworkの問題).ASP.NET MVCのオープンは成功の鍵であり、Entity Frameworkが成功するかどうかはオープンするかどうかにかかっている.
    2)ASP.NET WebFormsとASP.NET MVCは併存しますか?
    以前は併存すると思いましたが、今はASP.NET WebFormsのBugマイクロソフト自身も解決するのがおっくうですが、あなたはまだ併存すると信じていますか?