如果让验证码跟随表单提交,那验证码无论对错都需要执行一次提交过程,若错误则会再次返回,同时由于为了验证码的安全性,验证码在从session中获取到之后,需要进行删除操作,返回之后还需要刷新一次才可生成新的验证码,这样操作大大降低了用户体验,故采取Ajax的方式在每次验证码失去焦点时进行对验证码的校验。   在保证验证码安全性的方式上,一种是采取每次错误直接刷新,另一种是错误仅返回错误信息,并不刷新,获取验证码的session在表单提交之后另行删除。

实现验证码失去焦点时进行校验

  如果让验证码跟随表单提交,那验证码无论对错都需要执行一次提交过程,若错误则会再次返回,同时由于为了验证码的安全性,验证码在从session中获取到之后,需要进行删除操作,返回之后还需要刷新一次才可生成新的验证码,这样操作大大降低了用户体验,故采取Ajax的方式在每次验证码失去焦点时进行对验证码的校验。

  在保证验证码安全性的方式上,一种是采取每次错误直接刷新,另一种是错误仅返回错误信息,并不刷新,获取验证码的session在表单提交之后另行删除。

1. 校验错误即删除

  前台Javascript代码,对验证码输入框内容通过Ajax异步提交给servlet

//定义布尔型全局变量以提供给表单提交前的校验信息
var codeFlag;
function checkCode(){
    var code = $("#code").val();
    var flag = (code != null);
    if (flag){
        var code = $("#code").val();
        //Ajax提交验证码信息到servlet
        $.post("checkCodeServerServlet",{"code":code},function (data) {
            if (data.flag){
                $("#code").css("border","");
                codeFlag = true;
            }else {
                $("#code").css("border","1px solid red");
                //响应错误则刷新验证码,原因是session中的code信息已经删除
                //若不想删除则采用第二种,session中的code在提交表单之后进行删除
                changeCheckCode($("#codeImg")[0]);
                codeFlag = false;
            }
            $("#errorMsg").html(data.errorMsg);
        });
    } else {
        $("#code").css("border","1px solid red");
        codeFlag = false;
    }
}
$("#code").blur(checkCode);

提交之后servlet进行验证,此处在每次验证之后删除session中的code信息

String code = request.getParameter("code");
HttpSession session = request.getSession();
String checkcode_server = (String)session.getAttribute("CHECKCODE_SERVER");
//获取到session中的code立即removeAttribute
session.removeAttribute("CHECKCODE_SERVER");
ResultInfo info = new ResultInfo();
if (code.equalsIgnoreCase(checkcode_server)){
    info.setFlag(true);
}else {
    info.setFlag(false);
    info.setErrorMsg("验证码错误!");
}
//将info对象转换为json返回
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(info);
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);

2.验证码在校验失败时不刷新

前台代码

//7.验证验证码:非空
var codeFlag;
function checkCode(){
    var code = $("#code").val();
    var flag = (code != null);
    if (flag){
        var code = $("#code").val();
        $.post("checkCodeServerServlet",{"code":code},function (data) {
            if (data.flag){
                $("#code").css("border","");
                codeFlag = true;
            }else {
                $("#code").css("border","1px solid red");
                codeFlag = false;
            }
            $("#errorMsg").html(data.errorMsg);
        });
    } else {
        $("#code").css("border","1px solid red");
        codeFlag = false;
    }
}
$("#code").blur(checkCode);

验证码校验servlet

String code = request.getParameter("code");
HttpSession session = request.getSession();
String checkcode_server = (String)session.getAttribute("CHECKCODE_SERVER");
ResultInfo info = new ResultInfo();
if (code.equalsIgnoreCase(checkcode_server)){
    info.setFlag(true);
}else {
    info.setFlag(false);
    info.setErrorMsg("验证码错误!");
}
//将info对象转换为json返回
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(info);
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);

将如下代码放入表单提交的servlet中,这样就可以实现每次校验完无论是否错误不更改验证码内容,同时保证了验证码的安全性

HttpSession session = request.getSession();
session.removeAttribute("CHECKCODE_SERVER");