使用一个HttpModule拦截Http请求,来检测页面刷新(F5或正常的请求)
2015-01-20 11:07
751 查看
在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中的值就是上次页面提交的时候产生并保存的值。
2. 在server端,我们维护一个队列(Queue),存储每次页面提交产生的GUID。每次页面post back的时候,去读取Hidden Field中的值,如果该值在队列中已经存在的话,那页面是通过F5刷新的。
由于需要拦截HTTP请求,所以我们可以使用一个HttpModule,在HttpModule中可以注册Hidden Field和判断的一些操作。
HttpModule需要在Web.config中注册。
完整代码及Demo下载:RefreshModule.zip (下载次数:181)
原创文章,转载请注明: 转载自闲云博客
本文链接地址: 使用一个HttpModule拦截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或正常的请求)
相关文章推荐
- 使用layer的alert函数完成根据post请求结果弹出一个提示,然后刷新本页面
- 确认框的使用。弹出一个确认框,Ajax提交一个请求,刷新页面。
- 如果某个页面上点击按钮发起了一个http url请求,去执行一个action,但是还没等这个action完成,我就刷新了这个页面,然后又点击了这个按钮,这样之前的那次http url请求还在执行吗?
- 在HttpModule中使用gzip,deflate协议对aspx页面进行压缩
- 一个使用AJAX动态改变页面刷新的东东~~
- 使用 JavaScript 拦截和跟踪浏览器中的 HTTP 请求
- asp.net 处理F5刷新页面重复提交页面的一个思路
- HttpCompressionModule 6的一个Bug及使用效果
- 使用HttpModule(给页面添加页头和页尾,重写URL)
- 使用HttpModule控制SharePoint页面跳转
- 使用HttpHandler来监控HTML页面请求
- 使用服务端事件委托机制来防止页面重复提交数据或客户端浏览器使用(F5)刷新提交数据
- 在HttpModule中使用gzip,deflate协议对aspx页面进行压缩
- Asp.net使用HttpModule压缩并删除空白Html请求
- SERVER2008IIS服务器不能正常使用(由于扩展配置问题而无法提供您请求的页面,如果该页面是脚本...)
- Asp.net使用HttpModule压缩并删除空白Html请求
- 处理F5刷新页面重复提交页面的一个思路
- 使用jquery 如何编写实现请求本页面的无刷新操作
- asp.net 处理F5刷新页面重复提交页面的一个思路
- 在HttpModule中使用gzip,deflate协议对aspx页面进行压缩(转)