關於如何在Struts下使用jsp圖片驗證碼,請參考另外一篇文章html">《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);
參考鏈接:http://blog.kongxz.com/2010/01/solution-to-verifying-code-in-multiple-instances/