场景:一个基于Ajax技术的Web应用,采用的是多页面方式 ,每个页面内部使用Ajax实现复杂业务逻辑之间的无刷新切换,使用了Struts来实现MVC。
问题:对于Ajax请求,只有在通过用户验证无误之后才能对请求作出响应。如果用户长时间不做操作导致Session过时之后才发出请求,则此时应该跳转到出错页面,提示用户重新登录。对于非Ajax请求,可以自定义异常并针对此异常设置相应的出错页面。在用户信息验证失败的时候直接抛出此异常即可,web容器会自动捕捉到此异常并且显示出错页面;但是,对于Ajax请求,则不会如期待的那样自动跳转到出错页面。若不错特殊处理,Ajax请求的回调函数会得到意想不到的数据而导致程序出错。
分析:对于一个Ajax的应用,每一次客户端和服务器的数据交互,可以看成是在一个由客户端的XMLHttpRequest和服务器端的Servlet(这里假设用Servlet响应Ajax请求)组成的闭合管道(如图1)中进行的:
图1
所有从服务器端得到的数据流都会被XMLHttpRqeuest对象获得,然后由回调函数做出相应处理。
一般而言,用户登录之后,将用户信息是存放在Session中。做用户验证,其实就是检查此时Session中用户信息是否存在或者是否正确。如果在每次逻辑处理之前都去做这样的重复检查,并且检查的方法会发生改变,这样的程序既不精简还缺少可维护性。相信很少有人这么做。
比较好的做法是使用Filter(Servlet2.3之后才行)来做这样的通用检查,简单而且修改规则也很容易。Filter在应用中的作用之处如图2所示:
图2
另外,还可以添加具有不同功能的Filter,形成一个Filter链。
可以看到,在请求还没有到达Servlet之前,可以对请求作一些处理之后再提交给Servlet;在Servlet发出响应但还没有到达客户端之前,还可以对响应作处理。因此,作用户检查之类的工作由Filter来完成是比较合理的。
并不是说经过Filter的请求最终一定会到达Servlet。因为Filter有权操作Request和Response,所以Filter完全可以自己向客户端直接返回响应,从而中止此次交互:
图3
如图3所示,若是检查用户信息失败,Filter可以直接返回响应。
到这里,应该比较清楚了,在用户信息验证出错情况下,若要使得客户端能自动显示出错提示页面,应该让Ajax请求所对应的回调函数去做。
如果只是很简单的少数请求,则可以在Filter中返回出错标志,然后在回调函数中作判断进行相应的页面跳转处理。但是,对于一个复杂的应用,如果每个回调函数中都要添加这样的判断,或者服务器端定义的出错标志发生改变,则会大大降低程序的可维护性。
对于稍稍复杂的Ajax应用,一般都会使用一个共通的模块来操作Ajax的请求(比如创建跨浏览器的XMLHttpRequest对象等等)。如果能在这样的通用模块中具有可以在回调函数被调用之前获得服务器返回数据的能力,则可以做通用的出错判断,而不必修改每一个回调函数。
比如下面的这个通用模块:
function sendRequest(callback,data,method,url,async,sload,user,password)
...{
//创建XMLHttpRequest对象
var oj = createHttpRequest();
if( oj == null ) return null;
...
if(typeof callback=='object')...{
var callback_onload = callback.onload;
var callback_onbeforsetheader = callback.onbeforsetheader;
} else ...{
var callback_onload = callback;
var callback_onbeforsetheader = null;
}
oj.onload = function () ...{
callback_onload(oj);
}
...
oj.open(method, url, async, user, password);
...
oj.send(data);
}可以在callback_onload(oj); 之前添加对出错标志的判断。到此处,问题已经得到解决。
如果以后要更改出错标志或者是出错页面,则此处也要做相应的更改才行。如何能更“智能”一点呢?
既然Filter可以返回出错标志,那当然也可以返回javascript代码了!如果能在此处动态地执行一段代码,不就解决问题了吗?想到javascript的eval函数了吧!对,就是它!代码很简单:
oj.onload = function () ...{
try ...{
eval(oj.responseText);
} catch (e) ...{}
callback_onload(oj);
}如果是正常情况下返回的数据,eval函数执行后不会引起程序异常;如果是一段javascript代码,则会得到执行,客户端的Ajax调用也不要做任何修改。
返回到Filter,若是用户验证失败,并且是Ajax请求可以返回一段让页面自动跳转的javascript代码;若是普通的非Ajax请求,则可以放心地抛出异常。经过验证,在Ajax请求和非Ajax请求的情况下,二者的客户体验是相同的。对于页面跳转,其实方法很多,这里就省略代码了。
同理,如果继续添加用户权限检查等等的Filter,则可以地向客户端发出各种不同的javascript代码,很轻松实现相应的功能而客户端无需作修改。
总结:对于Ajax的请求,其数据流是封闭的,服务器发送给在客户端的数据都被XMLHttpRequest对象所获得。本文通过从Filter中发出javascript代码让其在客户端得到执行,从而可以在session过时验证用户信息失败之后,让客户端自动显示出错页面,与非Ajax请求时的客户体验相一致。对于Ajax请求,此方法进一步推广,可以直接在服务器端发出javascript让其在客户端得到执行。
PS:ajax请求在header里会多出这样的参数值对name:X-Requested-With value:XMLHttpRequest
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/owen4751076/archive/2008/07/23/2700501.aspx
分享到:
相关推荐
Javaweb项目Session超时解决方案 在Java Web开发中,Session机制为我们提供了许多方便,Session是由浏览器和服务器之间维护的。Session超时理解为:浏览器和服务器之间创建了一个Session,由于客户端长时间(休眠...
在Web开发中,Session是服务器用来跟踪用户状态的一种机制,它是服务器端存储用户信息的方式。在用户登录后,服务器会创建一个Session,并将用户的登录信息(如用户ID、用户名等)存储在这个Session对象中,然后将...
从内容上来看,文章内容的重复性可能是由于OCR扫描时识别错误或漏识别导致的,但核心内容表达清晰,即介绍了在使用AJAX进行前后端交互时,如何监测用户session状态,并在用户session失效时提供解决方案。这种解决...
本文将深入探讨phpcms中的session过期问题,并提供解决方案。 首先,我们需要理解session的工作原理。Session是通过在服务器端存储用户状态信息,每次用户请求时,通过session ID来识别用户。当用户长时间无操作...
1. **JSONP(JSON with Padding)**:JSONP是一种早期的跨域解决方案,但不适用于需要服务器端存储session的情况,因为它只能用于获取数据,无法设置Cookie。 2. **CORS(Cross-Origin Resource Sharing)**:CORS是...
由于Ajax通常返回JSON数据,JSON Hijacking是一种利用未受保护的JSON响应,强制加载到攻击者的网页中,从而控制用户的浏览器行为。防范方法包括设置正确的Content-Type为"application/json",避免被当作JavaScript...
- 第一种方法是遍历当前已加载的控制器,通过`this.application.controllers.keys`来检查控制器是否已经存在。 - 第二种方法是在功能菜单的数据源中设置一个状态变量(如status),在加载控制器后将其设置为true,...
另一种更稳定的方法是使用XMLHTTP对象(在现代浏览器中通常称为Ajax)在用户关闭页面前发送一个请求到服务器注销用户。在JavaScript中,创建一个XMLHTTP实例,当用户关闭页面时发送注销请求,然后关闭当前窗口。...
Struts框架是Java Web开发中常用的一个开源框架,它基于MVC(Model-View-Controller)设计模式,为开发者提供了一种结构化的解决方案,使得构建动态、数据驱动的Web应用变得更加简单。在“基于Struts框架的电子商务...
ASP(Active Server Pages)是微软公司推出的一种服务器端脚本环境,用于创建动态交互式网页。它允许开发人员将HTML、VBScript(Visual Basic Script)或JScript代码嵌入到网页中,使得网页在服务器端处理数据并生成...
Java 实现 Comet 长连接,服务器主动发送消息给客户端是一项关键的技术,它在实时通信、推送服务...同时,随着 WebSocket 的普及,它逐渐成为现代实时通信的首选技术,但 Comet 仍然是在某些场景下不可或缺的解决方案。
Spring Cloud则是一套微服务解决方案,包含了服务发现、负载均衡、配置中心等多个组件。 八、部署与运行 JavaWeb应用通常部署在应用服务器上,如Tomcat、Jetty等。WAR文件是Web应用的标准打包格式,包含所有资源和...
BlazeDS是一个Adobe提供的实时数据和远程调用解决方案,它可以作为Flex和Java之间的桥梁,实现双向数据流和远程过程调用。利用BlazeDS,Flex客户端可以订阅Java服务器上的事件,实时获取更新数据,同时也可以调用...
DWR是基于Ajax的一种技术,但它超越了传统的Ajax请求处理方式,提供了一种更为简单直观的方式来处理前后端的数据交互。通过DWR,开发者可以直接在JavaScript中调用服务器端的Java方法,而无需编写复杂的Ajax请求代码...
总的来说,这个在线人数统计程序提供了一种实用的解决方案,特别是在资源有限的免费Web托管服务中。通过避免对Global.asa的依赖,它拓宽了其适用范围,使得更多网站能够实现这一常见功能。在开发类似程序时,理解...
WebSocket是一种在客户端和服务器之间建立长连接的协议,它为实时数据交换提供了高效、低延迟的解决方案。在传统的HTTP协议中,每次通信都需要发起请求,然后等待响应,这样的模式对于实时性要求高的应用(如在线...
这种方式虽然效率不高,但在没有WebSocket等现代技术的情况下是常见的解决方案。 4. **显示在线用户**:ASP聊天室可以利用Session对象维护在线用户列表。每当用户登录,就在服务器端更新在线用户列表;用户退出时,...
#### 解决方案 为了解决这一问题,本文提出了一种改进的在线用户列表实现策略,通过引入`RefreshTime`属性和`Refresh.aspx`页面,结合XMLHttpRequest技术,实现了对用户状态的精确追踪。 ##### 关键组件与逻辑 1....
### 自整理Java关于基础和框架的面试题 #### 基础知识点 ##### JDK常用的包 - **java.lang**: 包含所有基本类,如`String`、`Math`等。...- Spring是一个开源框架,提供了一整套的企业级服务解决方案...
ASP.NET是一种基于.NET Framework的Web应用程序开发框架,由微软公司推出,主要用于构建动态网站、Web应用和服务。在“ASP.NET基于BS结构的实验室预约模型系统”中,我们探讨的是一个利用这种技术实现的在线实验室...