同时打开多个带验证码页面问题的一种解决方案
关于如何在Struts下使用jsp图片验证码,请参考另外一篇文章《jsp图片验证码》。其原理就是随机生成4位验证码,将其写入Session,同时生成图片显示出来。这样就出问题了。如果同时打开多个带验证码页面,那么只有最后的页面验证码会通过验证,其他的均提示验证码错误。
其实这个问题当初添加验证码功能的时候就知道会有,但是一直没改,因为很少有人打开多个登录页面,就算是出错了刷新一次就能解决。最近负责项目的师兄盯住这个问题了,所以不得不改改。
这个错误的关键代码在于:
request.getSession().setAttribute("checkcode",sRand);
也就是说每次生成验证码都存在Session的checkcode变量里。这样每次生成的验证码都会覆盖上次的值。
网上有许多解决方案,其中一种是给验证码加时间戳。
在将验证码存入Session时使用以下代码:
String timestamp=(String) request.getQueryString();//我这里就一个参数
request.getSession().setAttribute("checkcode"+timestamp,sRand);
其实原理很简单,就是加入时间戳,把存入Session的变量区别开来。
使用的时候在表单里加入:
<input id="timestamp" type="hidden" name="timestamp" value="">
同时写一个图片的刷新脚本
function loadimage(){
var timestamp=(new Date()).valueOf(); //timestamp.
document.getElementById("randImage").src = "<%=request.getContextPath()%>/image.jsp?"+timestamp;
document.getElementById("timestamp").value = timestamp;
}
服务器端直接在form的validate()里使用如下代码取出checkcode即可。
String checkcode= (String) request.getSession().getAttribute("checkcode"+timestamp);
用完记得顺手清理session:
request.getSession().removeAttribute("checkcode"+timestamp);
参考链接:https://blog.kongxz.com/2010/01/solution-to-verifying-code-in-multiple-instances/