- 浏览: 117668 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
cike8899:
jquery的blur在ie中不能用$('#poppan__o ...
IE和FF下输入框blur事件流程处理的差别引起的focus兼容性问题 -
Canace_lemon:
你好,请问你测试的时候是怎么解决的呢? 也就是你的DAO文件是 ...
JOTM事务管理时报JNDI错误问题,实在没辙了,熟悉JOTM的麻烦看下 -
love2java:
根据atian25的思路,我使用settimeout解决了问题 ...
IE和FF下输入框blur事件流程处理的差别引起的focus兼容性问题 -
lifesinger:
ie下有个事件 beforedeactive, 可以阻止失去焦 ...
IE和FF下输入框blur事件流程处理的差别引起的focus兼容性问题 -
atian25:
ff下 blur在focus之后,settimeout做个延迟 ...
IE和FF下输入框blur事件流程处理的差别引起的focus兼容性问题
来分析这样一种实际情况,即,在HTTP处理程序处理请求之前对请求进行筛选,这有助于实现一个原本不可能的特征。回发机制有一个严重的缺陷——如果用户刷新当前显示页面,则服务器上所采取的最后一个动作将盲目地重复。例如,如果作为前一次发送的结果添加了一个新记录,则应用程序会在另一次回发时试图插入一个完全相同的记录。当然,这会导致插入完全相同的记录,因而应当产生一个异常。这一缺陷自Web编程最先出现时就已经存在了,ASP.NET无疑不会引入它。要实现非重复的动作,必须采取一些对策,本质上将任何关键的服务器端操作转换为一个幂等性。在代数中,如果一个操作不管对它执行多少次结果都不变,我们就说该操作是幂等的。例如,看一看如下SQL命令:
DELETE FROM employees WHERE employeeid=9
我们可以对该命令连续执行1000次,但是最多只会删掉1个记录,即满足WHERE子句中设定的标准的记录。另请考虑如下命令:
INSERT INTO employees VALUES (...)
每次执行该命令,都有可能把一个新记录添加到employees表中。如果存在自动编码的键列或者非惟一的列,尤其会出现这种情况。如果表设计要求键是惟一的并且明确加以规定,则第2次运行该命令时会抛出一个SQL异常。
虽然刚才考虑的特殊情况通常在数据访问层(data access layer,简称DAL)解决,但是它的基本模式代表了大多数Web应用程序的一个常见方案。因此,待研究的问题是:怎样查明页面是因为一个显式的用户操作被回传,还是因为用户按下了F5键或页面刷新工具栏按钮呢?
1. 页面刷新操作的基本原理
页面刷新操作是一种内部浏览器操作,对此浏览器不会根据事件或回调提供任何外部通知。从技术上讲,页面刷新是由最新请求的“简单的”重复组成的。浏览器缓存它所服务的最新请求,并在用户按下页面刷新键或按钮时重新显示。我所知道的浏览器不会为页面刷新事件提供任何类型通知——即使有,无疑也不是一种公认标准。
据此可知,服务器端代码(例如,ASP.NET、经典ASP或ISAPI DLL)无法将刷新请求与一般的提交或回发请求相区分。为了帮助ASP.NET检测和处理页面刷新,我们需要创建外围机制,使两个在其他方面相同的请求看起来不同。所有已知的浏览器都是通过重新发送最后发送的HTTP请求来实现刷新;为了使该副本不同于原始请求,一个额外的服务必须添加其他参数,而 ASP.NET页面必须能够捕获它们。
我考虑了一些附加需求。解决方案不应依赖会话状态,而且不应使服务器内存负荷太重。它应该是相对容易部署的,而且应尽量不引人注目。
2. 解决方案的概要描述
本解决方案基于如下思想:每个请求被分配一个标签号,而HTTP模块将跟踪它处理的每个不同页面里最后服务的标签。如果该页面持有的标签号小于该页面的最后服务的标签,则只能表明服务了相同的请求——即,页面刷新。该解决方案由两个构造块组成:一个HTTP模块和一个自定义的页面类,前者对标签号作初步检查,后者自动地将一个渐进的标签号码添加到每个服务过的页面。使该特征起作用涉及两个步骤:首先,注册该HTTP模块;其次,在相关的应用程序中改变每个页面的基本的代码隐藏类以检测浏览器刷新。
HTTP模块位于HTTP运行库环境的中间,登记应用程序中的一个资源的每个请求。页面第一次被请求时(不是回发时),不分配任何标签。HTTP模块将生成一个新的标签号,并把它存储在HttpContext对象的Items集合中。此外,该模块将最后服务的标签的内部计数器初始化为0。随后该页面每次被请求时,该模块都将最后服务的标签与页面标签进行比较。如果页面标签更新一些,则该请求被认为是一次普通的回发;否则,它将被标记为一次页面刷新。表2.6总结了这两种场景及其相关的操作。
为了确保每个请求(除了第一次以外)都有一个合适的标签号,需要得到页面类的一些帮助。这就是为什么需要将每个打算支持该特征的页面的代码隐藏类设置为一个特定类——这是我们稍候将讨论的一个过程。该页面类将从HTTP模块接收两种不同的信息:要存储在随页面一起传送的一个隐藏字段中的下一个标签,以及该请求是否为页面刷新的信息。作为对开发人员的一项增值服务,代码隐藏类将提供一个额外的布尔属性:IsRefreshed,以允许开发人员了解请求是页面刷新还是常规回发。
*重要提示 HttpContext类上的Items集合是一个载体集合,是为了让HTTP模块将信息向下传递给实际负责服务请求的页面和HTTP处理程序而特意建立的。我们这里采用的HTTP模块在Items集合中设置两个数据项。一个数据项让页面知道请求是否为页面刷新;另一个数据项让页面知道下一个标签号是什么。让HTTP模块将下一个标签号传递给页面,满足使页面类的行为尽可能地简单和线性的目的,从而将大部分实现和执行负担转移给HTTP模块。
3. 解决方案的实现
我刚刚概述的解决方案有几个问题有待研究。首先,状态是必需的,我们把它保存在哪里?其次,对每个输入请求都将调用一个HTTP模块。如何区分对相同页面的请求呢?如何把信息传递给页面呢?你希望页面有多大的智能呢?
显然,这里所列的每个问题,都可以用不同于此处所介绍的方法进行设计和实现。为了得到一个可行的解决方案,这里作出的所有设计选择应当被认为是任意的,如果需要对该代码进行重新加工以更好地满足自己的目的,可以用等效的策略替换它。下一个实例中给出的代码版本,融入了我一直以来所收集的最宝贵的建议。这些建议之一如前一个重要提示所述,尽量将代码移到HTTP模块中。
如下代码展示了该HTTP模块的实现:
该模块监听BeginRequest事件,结束调用RefreshAction辅助类上的Check方法。
Check方法操作如下:它将最后服务的标签(如果有)与页面提供的标签进行比较。该页面将标签号存储在一个通过Request对象接口读入的隐藏字段中。HTTP模块维护一个散列表,服务的每个不同的URL都有一个表项。该散列表中的值存储该URL的最后服务的标签。
注意 Item索引器属性,来设置最后服务的标签,因为Item重写已有的项。如果数据项已经存在,则Add方法只是返回。
除了创建HTTP模块,我们还需要安排一个页面类,以用作需要检测浏览器刷新的页面的基类。下面给出了这个页面类的代码:
该示例页面定义了一个新的公共布尔属性IsRefreshed。我们可以在代码中以使用IsPostBack或IsCallback那样的方法使用该属性。该实例页面重写了OnPreRenderComplete方法,用页面标签添加隐藏字段。如前所述,该页面标签是通过Items集合中的一个特别的(并且是任意命名的)项从HTTP模块中得到的。
IsRefreshed属性允许我们决定在一个回发动作被请求时要做什么。在上述代码中,如果页面正在刷新,则不调用AddRecord方法。不用说,IsRefreshed仅适用于这里介绍的自定义页面类。自定义页面类并非只是添加该属性,它还要添加隐藏字段,这是该机制起作用所必不可少的。
转自:http://space.itpub.net/100788/viewspace-271432
DELETE FROM employees WHERE employeeid=9
我们可以对该命令连续执行1000次,但是最多只会删掉1个记录,即满足WHERE子句中设定的标准的记录。另请考虑如下命令:
INSERT INTO employees VALUES (...)
每次执行该命令,都有可能把一个新记录添加到employees表中。如果存在自动编码的键列或者非惟一的列,尤其会出现这种情况。如果表设计要求键是惟一的并且明确加以规定,则第2次运行该命令时会抛出一个SQL异常。
虽然刚才考虑的特殊情况通常在数据访问层(data access layer,简称DAL)解决,但是它的基本模式代表了大多数Web应用程序的一个常见方案。因此,待研究的问题是:怎样查明页面是因为一个显式的用户操作被回传,还是因为用户按下了F5键或页面刷新工具栏按钮呢?
1. 页面刷新操作的基本原理
页面刷新操作是一种内部浏览器操作,对此浏览器不会根据事件或回调提供任何外部通知。从技术上讲,页面刷新是由最新请求的“简单的”重复组成的。浏览器缓存它所服务的最新请求,并在用户按下页面刷新键或按钮时重新显示。我所知道的浏览器不会为页面刷新事件提供任何类型通知——即使有,无疑也不是一种公认标准。
据此可知,服务器端代码(例如,ASP.NET、经典ASP或ISAPI DLL)无法将刷新请求与一般的提交或回发请求相区分。为了帮助ASP.NET检测和处理页面刷新,我们需要创建外围机制,使两个在其他方面相同的请求看起来不同。所有已知的浏览器都是通过重新发送最后发送的HTTP请求来实现刷新;为了使该副本不同于原始请求,一个额外的服务必须添加其他参数,而 ASP.NET页面必须能够捕获它们。
我考虑了一些附加需求。解决方案不应依赖会话状态,而且不应使服务器内存负荷太重。它应该是相对容易部署的,而且应尽量不引人注目。
2. 解决方案的概要描述
本解决方案基于如下思想:每个请求被分配一个标签号,而HTTP模块将跟踪它处理的每个不同页面里最后服务的标签。如果该页面持有的标签号小于该页面的最后服务的标签,则只能表明服务了相同的请求——即,页面刷新。该解决方案由两个构造块组成:一个HTTP模块和一个自定义的页面类,前者对标签号作初步检查,后者自动地将一个渐进的标签号码添加到每个服务过的页面。使该特征起作用涉及两个步骤:首先,注册该HTTP模块;其次,在相关的应用程序中改变每个页面的基本的代码隐藏类以检测浏览器刷新。
HTTP模块位于HTTP运行库环境的中间,登记应用程序中的一个资源的每个请求。页面第一次被请求时(不是回发时),不分配任何标签。HTTP模块将生成一个新的标签号,并把它存储在HttpContext对象的Items集合中。此外,该模块将最后服务的标签的内部计数器初始化为0。随后该页面每次被请求时,该模块都将最后服务的标签与页面标签进行比较。如果页面标签更新一些,则该请求被认为是一次普通的回发;否则,它将被标记为一次页面刷新。表2.6总结了这两种场景及其相关的操作。
为了确保每个请求(除了第一次以外)都有一个合适的标签号,需要得到页面类的一些帮助。这就是为什么需要将每个打算支持该特征的页面的代码隐藏类设置为一个特定类——这是我们稍候将讨论的一个过程。该页面类将从HTTP模块接收两种不同的信息:要存储在随页面一起传送的一个隐藏字段中的下一个标签,以及该请求是否为页面刷新的信息。作为对开发人员的一项增值服务,代码隐藏类将提供一个额外的布尔属性:IsRefreshed,以允许开发人员了解请求是页面刷新还是常规回发。
*重要提示 HttpContext类上的Items集合是一个载体集合,是为了让HTTP模块将信息向下传递给实际负责服务请求的页面和HTTP处理程序而特意建立的。我们这里采用的HTTP模块在Items集合中设置两个数据项。一个数据项让页面知道请求是否为页面刷新;另一个数据项让页面知道下一个标签号是什么。让HTTP模块将下一个标签号传递给页面,满足使页面类的行为尽可能地简单和线性的目的,从而将大部分实现和执行负担转移给HTTP模块。
3. 解决方案的实现
我刚刚概述的解决方案有几个问题有待研究。首先,状态是必需的,我们把它保存在哪里?其次,对每个输入请求都将调用一个HTTP模块。如何区分对相同页面的请求呢?如何把信息传递给页面呢?你希望页面有多大的智能呢?
显然,这里所列的每个问题,都可以用不同于此处所介绍的方法进行设计和实现。为了得到一个可行的解决方案,这里作出的所有设计选择应当被认为是任意的,如果需要对该代码进行重新加工以更好地满足自己的目的,可以用等效的策略替换它。下一个实例中给出的代码版本,融入了我一直以来所收集的最宝贵的建议。这些建议之一如前一个重要提示所述,尽量将代码移到HTTP模块中。
如下代码展示了该HTTP模块的实现:
public class RefreshModule : IHttpModule { public void Init(HttpApplication app) { app.BeginRequest += new EventHandler(OnAcquireRequestState); } public void Dispose() { } void OnAcquireRequestState(object sender, EventArgs e) { HttpApplication app = (HttpApplication) sender; HttpContext ctx = app.Context; RefreshAction.Check(ctx); return; } }
该模块监听BeginRequest事件,结束调用RefreshAction辅助类上的Check方法。
public class RefreshAction { static Hashtable requestHistory = null; // Other string constants defined here public static void Check(HttpContext ctx) { // Initialize the ticket slot EnsureRefreshTicket(ctx); // Read the last ticket served in the session (from Session) int lastTicket = GetLastRefreshTicket(ctx); // Read the ticket of the current request (from a hidden field) int thisTicket = GetCurrentRefreshTicket(ctx, lastTicket); // Compare tickets if (thisTicket > lastTicket ||(thisTicket==lastTicket && thisTicket==0)) { UpdateLastRefreshTicket(ctx, thisTicket); ctx.Items[PageRefreshEntry] = false; } else ctx.Items[PageRefreshEntry] = true; } // Initialize the internal data store static void EnsureRefreshTicket(HttpContext ctx) { if (requestHistory == null) requestHistory = new Hashtable(); } // Return the last-served ticket for the URL static int GetLastRefreshTicket(HttpContext ctx) { // Extract and return the last ticket if (!requestHistory.ContainsKey(ctx.Request.Path)) return 0; else return (int) requestHistory[ctx.Request.Path]; } // Return the ticket associated with the page static int GetCurrentRefreshTicket(HttpContext ctx, int lastTicket) { int ticket; object o = ctx.Request[CurrentRefreshTicketEntry]; if (o == null) ticket = lastTicket; else ticket = Convert.ToInt32(o); ctx.Items[RefreshAction.NextPageTicketEntry] = ticket + 1; return ticket; } // Store the last-served ticket for the URL static void UpdateLastRefreshTicket(HttpContext ctx, int ticket) { requestHistory[ctx.Request.Path] = ticket; } }
Check方法操作如下:它将最后服务的标签(如果有)与页面提供的标签进行比较。该页面将标签号存储在一个通过Request对象接口读入的隐藏字段中。HTTP模块维护一个散列表,服务的每个不同的URL都有一个表项。该散列表中的值存储该URL的最后服务的标签。
注意 Item索引器属性,来设置最后服务的标签,因为Item重写已有的项。如果数据项已经存在,则Add方法只是返回。
除了创建HTTP模块,我们还需要安排一个页面类,以用作需要检测浏览器刷新的页面的基类。下面给出了这个页面类的代码:
// Assume to be in a custom namespace public class Page : System.Web.UI.Page { public bool IsRefreshed { get { HttpContext ctx = HttpContext.Current; object o = ctx.Items[RefreshAction.PageRefreshEntry]; if (o == null) return false; return (bool) o; } } // Handle the PreRenderComplete event protected override void OnPreRenderComplete(EventArgs e) { base.OnPreRenderComplete(e); SaveRefreshState(); } // Create the hidden field to store the current request ticket private void SaveRefreshState() { HttpContext ctx = HttpContext.Current; int ticket = (int) ctx.Items[RefreshAction.NextPageTicketEntry]; ClientScript.RegisterHiddenField( RefreshAction.CurrentRefreshTicketEntry, ticket.ToString()); } }
该示例页面定义了一个新的公共布尔属性IsRefreshed。我们可以在代码中以使用IsPostBack或IsCallback那样的方法使用该属性。该实例页面重写了OnPreRenderComplete方法,用页面标签添加隐藏字段。如前所述,该页面标签是通过Items集合中的一个特别的(并且是任意命名的)项从HTTP模块中得到的。
public partial class TestRefresh : ProAspNet20.CS.Components.Page { protected void AddContactButton_Click(object sender, EventArgs e) { Msg.InnerText = "Added"; if (!this.IsRefreshed) AddRecord(FName.Text, LName.Text); else Msg.InnerText = "Page refreshed"; BindData(); } }
IsRefreshed属性允许我们决定在一个回发动作被请求时要做什么。在上述代码中,如果页面正在刷新,则不调用AddRecord方法。不用说,IsRefreshed仅适用于这里介绍的自定义页面类。自定义页面类并非只是添加该属性,它还要添加隐藏字段,这是该机制起作用所必不可少的。
转自:http://space.itpub.net/100788/viewspace-271432
发表评论
-
ajf
2012-08-05 22:51 0http://liuzhijun.iteye.com/bl ... -
vim
2010-09-17 19:43 0http://www.orsoon.com/Soft/1100 ... -
DWR 收集
2009-08-19 07:32 0http://directwebremoting.org/dw ... -
全面理解javascript的caller,callee,call,apply概念
2009-08-18 20:05 840在提到上述的概念之前,首先想说说javascript中函数 ... -
IE和FF下输入框blur事件流程处理的差别引起的focus兼容性问题
2009-07-31 11:51 7266问题抛出:FF下,在输入框的blur事件中无法再让该输入框获取 ... -
怎样卸载IE7?
2009-07-08 21:54 1576How do I... Uninstall Microsoft ... -
Slick Edit2009 资料收集
2009-06-13 13:22 979http://www.verycd.com/topics/27 ... -
分析clientHeight、offsetHeight、scrollHeight
2009-06-08 00:06 1109分析clientHeight、offsetHeight、scr ... -
JUnit & Ant
2009-04-21 08:04 831http://www.aybook.cn/book/17522 ... -
the javascript goods
2009-03-17 20:36 0http://www.iteye.com/topic/2112 ... -
Maven References
2009-03-16 00:24 834Maven References Maven R ... -
apply, call , delete等的使用
2009-02-28 16:20 0apply, call , delete等的使用 水平滚动 ... -
javascript 101 tips
2009-02-24 20:20 0multiplication (*), division (/ ... -
Tomcat的Server.xml文件详解
2009-02-23 21:59 8042Tomcat是流行的JSP服务器 ... -
lesssons
2009-02-05 08:06 0第五章的代码 第五章的代码 第五章的代码 -
MyEclipse7 注册源码
2009-01-04 22:32 916刚装好并注册了, 不知JRE怎么使用1.5的, 没明白的太多了 ... -
这样获取页面中控件的属性?
2008-11-17 11:22 925在FIREFOX中, 可以直接通过ctrobj.attribu ... -
some links
2008-10-30 20:14 0http://coderdream.iteye.com/blo ... -
Java World乱码问题根源之所在
2008-08-20 21:09 1098本文介绍了编码字符集 ... -
数据库设计中的14个技巧
2008-08-14 15:49 13521. 原始单据与实体之间 ...
相关推荐
### 基于AJAX的Web无刷新页面快速更新数据方法 #### 1. 问题背景与需求 在传统的Web应用开发中,浏览器与服务器之间的交互通常依赖于HTTP请求/响应模式。具体而言,每当用户在Web应用界面进行操作时(如点击按钮或...
通过JavaScript或者AJAX(Asynchronous JavaScript and XML),开发者可以让网页内容随着用户的交互而实时更新,无需刷新整个页面。此外,HTML5引入了许多新特性,如Canvas、SVG等,它们使得网页可以呈现更多样的...
文档还提及了Ajax的基本特征,包括异步性、不需要页面刷新即可与服务器通信、以及在用户与服务器之间充当代理的作用等。在讨论Ajax的替代技术时,提到了Sun的Java Web Start、Microsoft的ClickOnce以及基于Flash的...
AJAX 广泛应用于各种场景,如实时聊天、表单验证、动态加载内容、地图服务等,提供无需整个页面刷新的互动体验。在这些场景中,重要的是利用好异步交互特性,提升用户体验,而不仅仅是实现无刷新效果。 总结: ...
Ajax(Asynchronous JavaScript and XML)技术则是ASP.NET中的一个重要组成部分,用于实现页面的部分刷新,提高用户体验。在ASP.NET中,Ajax允许在不重新加载整个网页的情况下与服务器交换数据并更新部分网页内容。 ...
同时,可以使用AJAX技术实现页面的无刷新更新,提高用户体验。 6. **安全性与性能优化**:考虑到网站的稳定性和安全性,需要处理如SQL注入、XSS攻击等问题。同时,通过缓存策略、负载均衡、数据库索引等方式,可以...
- **Gmail**:在查看邮件时,使用AJAX加载不同邮件的内容,无需刷新整个页面。 - **Google Maps**:用户可以平滑地拖动和缩放地图,地图数据在后台异步加载。 - **Flickr**:雅虎的图片分享平台,使用AJAX实现实时...
- 1KB页面大小,其中行地址为A0到A11,列地址为A0到A8 - 四银行操作模式 - CAS延迟(CL)可选3、4、5、6、7;附加延迟(AL)可选0、1、2、3、4、5 - 爆发类型:连续和交错模式 - 爆发长度:4、8 4. 输入/输出...
Ajax允许在不刷新整个页面的情况下进行局部更新,极大地提升了用户体验。而JSP(Java Server Pages)作为基于Java的动态网页技术,与Ajax的结合实现了服务器端和客户端的完美协作,提供了跨平台和负载均衡的解决方案...
JSP指令用于设置JSP页面的行为特征。常见的指令包括: - **`@page` 指令**:用于指定整个JSP页面的一些属性,如语言、导入的类等。 - `language`:指定脚本语言,默认为Java。 - `import`:导入包或类,多个导入...
注意:安装后,刷新任何打开页面以启用屏幕旋转。介绍ReadInbed,Chrome Extension,让您以您想要的方式定位屏幕!只需单击一下按钮,请在任何方向上快速旋转屏幕以供您查看乐趣。此扩展将按钮添加到Chrome浏览器中...
页面刷新后,向下滚动,直到看到指向现已部署页面的链接。 分叉存储库 您可以派生存储库,并使用自己的帐户为自己创建一个副本。 登录GitHub并找到 。 找到“存储库设置”按钮旁边的“叉子”按钮。 转到存储库,...
Ajax(Asynchronous JavaScript and XML)是一种在不刷新整个页面的情况下,与服务器交换数据并更新部分网页的技术。它通过XMLHttpRequest对象与服务器进行通信,提高了用户体验。 后端采用Struts2框架,这是一个...
特征支持LTR(从左到右)和RTL(从让到)语言同时转换多个md文件您可以分别转换多个md文件。 您可以串联多个md文件并将它们转换为一个HTML页面(选择一些md文件后,选中“ concatenate”复选框,查看呈现的HTMl页面...
DHTML是一种在网页中创建动态交互效果的技术,它结合了HTML、CSS、JavaScript以及DOM(Document Object Model)来实现页面的动态更新,而无需刷新整个页面。在这个案例中,DHTML被用来创建一个模拟(analog)时钟,即...
Django的模板系统允许开发者将动态内容嵌入到静态页面中,结合Ajax技术,可以实现无刷新的交互体验。Bootstrap框架可以快速构建响应式布局,确保在不同设备上都能良好展示。 为了保证项目的正常运行,需要设置合适...
项目现场 文档和源代码 技术领域HTML 5 CSS JavaScript特征SPA(单页应用程序)-无需刷新即可在子页面之间立即转换(JavaScript) CSS Web字体图标字体多语言用户界面(客户端-JavaScript) 英语抛光主题和其他显示...
模拟单页应用程序(适用于支持html5历史api的浏览器)(页面变化不完全刷新) 多语言支持(使用 2 种语言),可通过网址访问不同语言的页面(SEO 友好) 注意:界面的感觉和外观、图像、颜色和字体样式都是从复制...