HttpModuleを使用してHttp要求をブロックし、ページリフレッシュ(F 5または通常の要求)を検出する

10124 ワード

Webアプリケーションでは、「httpリクエストがF 5でリフレッシュされたリクエストなのか、正常にコミットされたリクエストなのか、どうやって判断するのか」という質問があります.
ASPを知っていると信じています.NETの人は私が何を言っているのか知っていて、同感します.そして、これは実はeasyの問題ではありません.それは,HTTPプロトコルの無状態の特性が要求間の状態保持を許さないためである.
 
多くの人がこの問題に注目しているのは、ページpostの時やその後、ブラウザが繰り返し提出したくないからだと思います.
問題は、「POSTリクエストがF 5ボタンでトリガーされたのか、正常なページインタラクションなのか、どうやって判断するのか」と簡単に説明できます.
幸いなことに、このときDOMの簡単な詳細はこの問題を解決するために使用することができます.それは、通常のページインタラクションを通じてPOSTの一部のデータがバックグラウンドに到着すると、formのonsubmitイベントがトリガーされ、F 5ボタンを押してPOSTの同じページをserver側に再起動すると、イベントはトリガーされません.これまで主流のブラウザでは、IE 6/7/8、Firefox 3.x、Chromeなどでは、こんな感じです.
 
上記の発見を利用して、私たちは以下の方法で上記の問題を解決することができます.
1.formのonsubmitイベント(ページフォームが発行されるたびにこのイベントが呼び出される)では、GUIDが生成され、このGUIDがページ上のHidden Fieldに付与される.
これにより、ページがコミットされるたびにserver側でこのHidden Fieldの値を表示することができ、F 5リフレッシュであれば、このHidden Fieldの値は前回ページがコミットされたときに生成され保存された値である.
01    function newGuid() {

02        var g = "";

03        for (var i = 0; i < 32; i++) {

04            g += Math.floor(Math.random() * 0xF).toString(0xF);

05        }

06        return g;

07    }

08     

09    //gets a new guid and assigns its value to the hidden field

10    function createPageIdentifier() {

11        var guid = this.newGuid();

12        document.getElementById('__REFRESH_FIELD').value = guid;

13    }

 
2.server側では、ページ送信ごとに生成されたGUIDを格納するキュー(Queue)を維持します.ページpost backごとにHidden Fieldの値を読み出し、キューに既に存在する場合はF 5で更新します.
HTTPリクエストをブロックする必要があるため、HttpModuleを使用して、HttpModuleにHidden Fieldと判断のいくつかの操作を登録することができます.
01    private static Guid GetPageGuid(Page page)

02            {

03                string str = page.Request.Form["__REFRESH_FIELD"];

04                return (!string.IsNullOrEmpty(str) ? new Guid(str) : Guid.Empty);

05            }

06     

07            public void Init(HttpApplication application)

08            {

09                guids = new Queue(queueSize);

10     

11                application.PreRequestHandlerExecute += new EventHandler(RefreshModule.Application_PreRequestHandlerExecute);

12            }

13     

14            private static void Page_Init(object sender, EventArgs e)

15            {

16                Page page = sender as Page;

17                if (page != null)

18                {

19                    page.ClientScript.RegisterOnSubmitStatement(typeof(RefreshModule), "onsubmit", "createPageIdentifier();");

20                    page.ClientScript.RegisterHiddenField("__REFRESH_FIELD", "");

21     

22                    HttpContext.Current.Items["IsRefreshed"] = false;

23                    if (page.Request.HttpMethod == "POST")

24                    {

25                        Guid pageGuid = GetPageGuid(page);

26                        bool flag = guids.Contains(pageGuid);

27                        HttpContext.Current.Items["IsRefreshed"] = flag;

28                        if (!flag && (pageGuid != Guid.Empty))

29                        {

30                            guids.Enqueue(pageGuid);

31                            if (guids.Count > queueSize)

32                            {

33                                guids.Dequeue();

34                            }

35                        }

36                    }

37                }

38            }

 
HttpModuleはWeb.configに登録します.
1    <httpmodules>

2      <add name="RefreshModule" type="Jianyun.RefreshModule.RefreshModule, RefreshModule">

3    </add></httpmodules>

 
完全なコードとDemoのダウンロード:
RefreshModule.zip(ダウンロード回数:181)
オリジナル文章、転載は明記してください:転載はブログから
このリンク先:HttpModuleを使用してHttp要求をブロックし、ページリフレッシュ(F 5または通常の要求)を検出する