• 使用一个HttpModule拦截Http请求,来检测页面刷新(F5或正常的请求)


    在Web Application中,有个问题就是:“我怎么来判断一个http请求到底是通过按F5刷新的请求还是正常的提交请求?”
    相信了解ASP.NET的人知道我在说什么,会有同感,而且这其实不是一个很easy的问题。那是因为HTTP协议无状态的特性不允许请求之间保持状态。
    我想大多数人关注这个问题是因为,页面post的时候或之后,不想浏览器重复提交。
    所以问题可以简化为:“我怎么来判断一个POST请求到底是由F5按钮触发的还是正常的页面交互?”
    幸运的是,这时候DOM的一个简单细节可以用来解决这个问题。那就是当你通过正常的页面交互,POST一些数据到后台的时候,会触发form的onsubmit事件,而当你按F5按钮来重新POST相同的页面到server端的时候,并不会触发该事件。目前为止,在主流的浏览器,IE6/7/8,Firefox 3.x,Chrome等中,都是这样子的。
    利用上面的这个发现,我们可以按以下方法来解决上面的问题:
    1. 在form的onsubmit事件中(每次页面表单提交的时候都会调用这个事件),产生一个GUID,并把这个GUID赋给页面上的一个Hidden Field。
    这样每次页面提交后,我们都可以在server端查看这个Hidden Field中的值,如果是F5刷新的话,这个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端,我们维护一个队列(Queue),存储每次页面提交产生的GUID。每次页面post back的时候,去读取Hidden Field中的值,如果该值在队列中已经存在的话,那页面是通过F5刷新的。
    由于需要拦截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请求,来检测页面刷新(F5或正常的请求)

  • 相关阅读:
    根据View找控制器
    ScrollView双击图片定点放大
    iOS消息推送原理和实现总结
    iOS完整学习路线图
    获取设备版本
    UIView与CALayer的区别,很详细
    iOS开发网络数据之AFNetworking使用
    (已实践)PLSQL本地还原Oracle数据库dmp文件
    所遇Oracle错误代码
    Dapper基本使用
  • 原文地址:https://www.cnblogs.com/tianma3798/p/4235526.html
Copyright © 2020-2023  润新知