1. 在使用ajax 注册时如果点击了后退按钮。重新注册该用户时不会提示该用户已经注册(前面已经注册了)。
在FireFox,google的chrom浏览器中运行该程序,当我们每次点击后不会出现该问题。在maxthon 双核浏览器的高速模式和隐私浏览窗口也没这种问题。但在maxthon的 IE内核模式就会出现这种问题。
2. 为什么只在IE浏览器中存在这个问题。我们使用HttpWatch工具拦截所有从浏览器中发出的请求,两次发出请求的时候情况如下:
我们发现第二次点击按钮的时候,请求没有向服务器发出,而是直接取出了cache(缓存)中的数据作为响应数据返回。为什么会有这种现象?
因为浏览器为了提高浏览网页的速度,会保存曾经浏览过的内容,如果用户请求了曾今访问过的夜间,浏览器就会判断是否可以使用缓存中的内容,如果可以,就不再向服务器发出请求,而直接使用缓存中的内容。
浏览器一般按照以下几个条件判断缓存是否可用:
1). 对POST方式的请求一般不使用缓存
2). 对GET请求,主要查看请求的地址是否与缓存中请求的地址一致,默认情况下如果地址一致而上一次请求返回的内容又被缓存了,此时就不再向服务器发出请求,而直接使用缓存中的内容。
解决办法:
个人以访126邮箱登录为例:
①变get方式为Post方式。
//网易登录。 用户名输入框失去焦点。 var params={ ajaxurlwithparam:"checkuname.do?uname="+uname, method:"get", data:"" }; checkresult=ajaxRequest(params);
此时会记录缓存。
即当你注册一个用户后点击IE 内核浏览器的后退按钮重新输入该用户名会提示"恭喜,该邮件地址可注册"。
而不是该用户已经注册。说明IE内核浏览器使用了缓存。没有向服务器提交ajax 验证请求。
把代码改为如下就可以了:
var params={ ajaxurlwithparam:"CheckUserExist?uname="+uname, method:"post", data:{uname:uname} }; checkresult=ajaxRequest(params);
服务器端验证代码如下:
String name=(String)request.getParameter("uname"); String username126=name+"@126.com"; String username163=name+"@163.com"; String usernameyeah=name+"@yeah.net"; UserDao userDao=new UserDao(); response.setContentType("application/json;charset=UTF-8"); response.setCharacterEncoding("UTF-8"); PrintWriter pw = response.getWriter(); JSONObject obj=new JSONObject(); if(userDao.checkRegUserName(username126)){ obj.put("mail126",new Boolean(true)); System.out.println("126-is-ok"); }else{ obj.put("mail126",new Boolean(false)); System.out.println("126-is-not"); } if(userDao.checkRegUserName(username163)){ obj.put("mail163",new Boolean(true)); System.out.println("163-is-ok"); }else{ obj.put("mail163",new Boolean(false)); System.out.println("163-is-not"); } if(userDao.checkRegUserName(usernameyeah)){ obj.put("mailyeah",new Boolean(true)); System.out.println("yeah-is-ok"); }else{ obj.put("mailyeah",new Boolean(false)); System.out.println("yeah-is-not"); } obj.put("vip163",new Boolean(false)); obj.put("vip126",new Boolean(false)); obj.put("vip188",new Boolean(false)); pw.print(obj); pw.flush();
(注意:在用get方法提交时应该写在doGet()方法里,如用post 方法提交时应该写在doPost()方法里)
②加时间戳
var params={ ajaxurlwithparam:"CheckUserExist?uname="+uname+"&t="+new Date().valueOf(), method:"get", data:"" }; checkresult=ajaxRequest(params);
此时注册后,点击后退按钮重新输入刚才注册的用户名不会出现那种异常。
即会提示“改用户名已经注册”的信息。
③在服务器端添加响应头(Response Header)内容,指明不要缓存
response.addHeader("pragma""no-cache");
response.addHeader("cache-control""no-cache");
此时可以把代码改为不用时间戳和使用get方式提交同样达到效果。
(note:具体哪种方式最好,还不知道。但个人觉得时间戳即②方法比较好。)