在开发个人中心时,越来越多的功能用到了ajax请求处理,比如收货地址、优惠券和订单管理,每次在写ajax时会出现重复写入ajax异常处理或用户超时处理,当用户超时地址改变时,则很多相同的ajax异常处理或者用户超时都需要修改,给维护带来了工作量。
Ajax请求时,服务器可以从header信息中查询是否x-requested-with并且值等于XMLHttpRequest来确定该请求来自ajax请求,这样我们就可以处理ajax请求session超时的问题。
public class UserInterceptor extends HandlerInterceptorAdapter {
private static final String LOGIN = "/login";
/** ajax请求响应头会有,x-requested-with */
private static final String X_REQUESTED_WITH = "x-requested-with";
/** 异步请求标准 */
private static final String XML_HTTP_REQUEST = "XMLHttpRequest";
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
super.postHandle(request, response, handler, modelAndView);
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 请求的路径
String contextPath = request.getContextPath();
String url = request.getServletPath().toString();
HttpSession session = request.getSession();
User user = (User) session.getAttribute(Constants.SESSION_USER);
if (StringUtils.isEmpty(user)) {
// 被拦截,重定向到login界面
StringBuilder urlBuilder = new StringBuilder(contextPath).append(LOGIN).append("?back=" + URLEncoder.encode(url, Constants.DEFAULT_ENCODE));
String xRequestedWith = request.getHeader(X_REQUESTED_WITH);
if (xRequestedWith != null && xRequestedWith.equalsIgnoreCase(XML_HTTP_REQUEST)) {
// 如果是ajax请求
response.setHeader("sessionstatus", "timeout");
response.setHeader("locationURL", new StringBuilder(contextPath).append(LOGIN).toString());
return false;
}
response.sendRedirect(urlBuilder.toString());
return false;
}
return true;
}
如果是ajax请求,我们设置头信息 sessionstatus 为timeout,还可以设置其他想要的头信息。ajax接到这个请求后如何处理则交给一个ajax请求的全局配置,来进行转向。
下面是zepto的ajax全局配置:
//使用zepto框架 全局的ajax访问,处理ajax清求时sesion超时
$.ajaxSettings.timeout = 30000;// (默认: 0): 以毫秒为单位的请求超时时间, 0 表示不超时。
$.ajaxSettings.complete = function(XMLHttpRequest, textStatus) {
var sessionstatus = XMLHttpRequest.getResponseHeader("sessionstatus"); // 通过XMLHttpRequest取得响应头,sessionstatus,
if (sessionstatus == "timeout") {
alert("用户帐号异常,请重新登录");
var locationURL = XMLHttpRequest.getResponseHeader("locationURL"); // 通过XMLHttpRequest取得响应头,locationURL,
// 如果超时就处理 ,指定要跳转的页面
window.location.href = locationURL;
}
}
$.ajaxSettings.error = function(XMLHttpRequest, textStatus) {
alert(textStatus);
switch (XMLHttpRequest.status) {
case (500):
alert("服务器系统内部错误");
break;
case (401):
alert("未登录");
break;
case (403):
alert("无权限执行此操作");
break;
case (408):
alert("请求超时");
break;
default:
alert("未知错误");
}
}
下面写了一个jquery的初步模型处理
//使用jquey全局的ajax访问,处理ajax清求时sesion超时
$.ajaxSetup({
timeout : 30000,
contentType : "application/x-www-form-urlencoded;charset=utf-8",
complete : function(XMLHttpRequest, textStatus) {
var sessionstatus = XMLHttpRequest.getResponseHeader("sessionstatus"); // 通过XMLHttpRequest取得响应头,sessionstatus,
if (sessionstatus == "timeout") {
alert("用户帐号异常,请重新登录");
var locationURL = XMLHttpRequest.getResponseHeader("locationURL"); // 通过XMLHttpRequest取得响应头,转向登陆页面locationURL,
// 如果超时就处理 ,指定要跳转的页面
window.location.href = locationURL;
}
},
error : function(jqXHR, textStatus, errorThrown) {
switch (jqXHR.status) {
case (500):
alert("服务器系统内部错误");
break;
case (401):
alert("未登录");
break;
case (403):
alert("无权限执行此操作");
break;
case (408):
alert("请求超时");
break;
default:
alert("未知错误");
}
}
})