在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中的值就是上次页面提交的时候产生并保存的值。
    function newGuid() {
var g = "";
for (var i = ; i < ; i++) {
g += Math.floor(Math.random() * 0xF).toString(0xF);
}
return g;
} //gets a new guid and assigns its value to the hidden field
function createPageIdentifier() {
var guid = this.newGuid();
document.getElementById('__REFRESH_FIELD').value = guid;
}
2. 在server端,我们维护一个队列(Queue),存储每次页面提交产生的GUID。每次页面post back的时候,去读取Hidden Field中的值,如果该值在队列中已经存在的话,那页面是通过F5刷新的。
由于需要拦截HTTP请求,所以我们可以使用一个HttpModule,在HttpModule中可以注册Hidden Field和判断的一些操作。
    private static Guid GetPageGuid(Page page)
{
string str = page.Request.Form["__REFRESH_FIELD"];
return (!string.IsNullOrEmpty(str) ? new Guid(str) : Guid.Empty);
} public void Init(HttpApplication application)
{
guids = new Queue(queueSize); application.PreRequestHandlerExecute += new EventHandler(RefreshModule.Application_PreRequestHandlerExecute);
} private static void Page_Init(object sender, EventArgs e)
{
Page page = sender as Page;
if (page != null)
{
page.ClientScript.RegisterOnSubmitStatement(typeof(RefreshModule), "onsubmit", "createPageIdentifier();");
page.ClientScript.RegisterHiddenField("__REFRESH_FIELD", ""); HttpContext.Current.Items["IsRefreshed"] = false;
if (page.Request.HttpMethod == "POST")
{
Guid pageGuid = GetPageGuid(page);
bool flag = guids.Contains(pageGuid);
HttpContext.Current.Items["IsRefreshed"] = flag;
if (!flag && (pageGuid != Guid.Empty))
{
guids.Enqueue(pageGuid);
if (guids.Count > queueSize)
{
guids.Dequeue();
}
}
}
}
}
HttpModule需要在Web.config中注册。
    <httpmodules>
<add name="RefreshModule" type="Jianyun.RefreshModule.RefreshModule, RefreshModule">
</add></httpmodules>
完整代码及Demo下载:RefreshModule.zip (下载次数:181)

原创文章,转载请注明: 转载自闲云博客

本文链接地址: 使用一个HttpModule拦截Http请求,来检测页面刷新(F5或正常的请求)

使用一个HttpModule拦截Http请求,来检测页面刷新(F5或正常的请求)的更多相关文章

  1. ASP.NET WebForm 检测页面刷新(Refresh)

    本文是翻译贴, 原文参见Detecting browser 'Refresh' from Code behind in C# 浏览器的"刷新"常会导致问题, 特别是当页面和数据库有 ...

  2. js 检测页面刷新或关闭

    window.onbeforeunload=function(){ //要提交的内容 return "随意写";//必须有return ,不然只有ie有效,chrome无效 }

  3. IIS7的集成模式下如何让自定义的HttpModule不处理静态文件(.html .css .js .jpeg等)请求

    今天将开发好的ASP.NET站点部署到客户的服务器上后,发现了一个非常头疼的问题,那么就是IIS7的应用程序池是集成模式的话,ASP.NET项目中自定义的HttpModule会处理静态文件(.html ...

  4. 一个vue请求接口渲染页面的例子

    new Vue({ el:'#bodylist', data: { list: [ { "type_id": "1", "type_name" ...

  5. 学习ASP.NET Core, 怎能不了解请求处理管道[3]: 自定义一个服务器感受一下管道是如何监听、接收和响应请求的

    我们在<服务器在管道中的"龙头"地位>中对ASP.NET Core默认提供的具有跨平台能力的KestrelServer进行了介绍,为了让读者朋友们对管道中的服务器具有更 ...

  6. 检测到有潜在危险的 Request.Form 值。 说明: ASP.NET 在请求中检测到包含潜在危险的数据

    在请求方法的顶部添加        [ValidateInput(false)]就OK了 从客户端(Content=" sdfdddd ...")中检测到有潜在危险的 Reques ...

  7. Postman 是一个非常棒的Chrome扩展,提供功能强大的API & HTTP 请求调试

    Postman 是一个非常棒的Chrome扩展,提供功能强大的API & HTTP 请求调试   需要FQ才能安装,使用时应该不用FQ了,除非使用postman的历史记录功能:   非常棒的C ...

  8. 拦截器(Inteceptor),过滤器(Filter),切面(Aspect)处理HttpServiceReqeust请求

    1.拦截器 java里的拦截器是动态拦截Action调用的对象.它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可 ...

  9. Web APi之捕获请求原始内容的实现方法以及接受POST请求多个参数多种解决方案(十四)

    前言 我们知道在Web APi中捕获原始请求的内容是肯定是很容易的,但是这句话并不是完全正确,前面我们是不是讨论过,在Web APi中,如果对于字符串发出非Get请求我们则会出错,为何?因为Web A ...

随机推荐

  1. J2EE项目开发流程简介

    开发流程(一) 提出需求:产品部提出本周期项目的具体需求. 项目计划:项目经理协调开发部.测试部和产品部进行需求协商,产生项目计划. 需求理解:开发部和测试部向产品部提出各自对需求的理解. 产品设计: ...

  2. UVA 221 - Urban Elevations(离散化)!!!!!!

    题意:给出一张俯视图.给出N个建筑物的左下标,长度,宽度,高度.现在求,从南面看,能看到那些建筑? Sample Input 14 160 0 30 60 30 125 0 32 28 60 95 0 ...

  3. php中mail()改用msmtp发送邮件

    php中的mail()函数默认调用的是sendmail,这次我将其换成了轻量级的msmtp.在次过程中涉及到:修改配置文件php.ini,创建配置文件msmtprc或(.msmtprc)并修改其权限. ...

  4. Centos安装php提示virtual memory exhausted: Cannot allocate memory

    由于内存不够,需要在php配置的时候./configure最后添加上 --disable-fileinfo >>./configure --prefix= ...........   -- ...

  5. js继承模式

    组合继承是js常用的继承模式,指的是将原型链和借用构造函数的技术结合在一起.其中的思想是使用原型链实现原型属性和方法的继承, 而通过借用构造函数实现对属性的继承. 例子: <script> ...

  6. 自动运行native2ascii 命令的Bat文件的编写

        使用eclipse开发,对于.properties文件的国际化,如果不使用插件对文件进行转码,则需要使用native2ascii命令自行对文件进行转码.     为了更方面的执行此操作,我将该 ...

  7. js原生Ajax的封装与使用

    一.原生Ajax代码的封装如下: (function() { var XHR = { createStandardXHR: function() { return new XMLHttpRequest ...

  8. HTML5_1

    2014,新年伊始,我不再是那个憧憬离开大学校园.过自由生活的傻丫头了.23岁,时间荏苒,差不多四分之一的人生已悄然逝去,大学生活差不多也快要画上句号了.工作.工作永远都是人生的一部分.曾想着随便找一 ...

  9. php 实现传入参数的传出

    类似于.net的out功能,php中可以使用&实现 如下示例: <?php$x=2; inOutFunction($x); function inOutFunction(&$x) ...

  10. [C入门 - 游戏编程系列] 贪吃蛇篇(一) - 世界定义

    每个游戏都有一个很明确的目的或者说游戏主题,贪吃蛇的目的很明确:蛇找到并吃掉食物.只有目的是很无聊的,算不上一个好游戏.所以设计者增加了创意:1. 吃掉食物后蛇会增长:2. 吃掉食物后分数会增加.有些 ...