使用Ajax开展验证码的刷新

使用Ajax进行验证码的刷新

利用Ajax实现验证码的刷新

废话不多说,大部分网站都有设置验证码防止恶意攻击。现在用最简单的实现进行我们的验证码刷新。
注册页面:login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
 
  <script src="../js/check_login.js" type="text/javascript"></script><!--这里的路径要这样设置  -->
    <base href="<%=basePath%>">
   
    <title>欢迎登陆</title>
   
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">   
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!-- 这里会需要引入外部的CSS文件,路径如下 -->
<link rel="stylesheet" type="text/css" href="CSS/style.css">


  </head>
  <style type="text/css">
 
 
 
  </style>
  <body>
 
  <div id="main">
  <form method="post" action="user/checkUserLogin.jsp">
   <table align="left">
   <tr>
   <td>用户名:</td>
   <td><input type="text" name="username" id="username" onchange="return check_username() == true;"></td>
   <td></td>
   <td><div id="display_username" class="display"></div></td>
   </tr>
   <tr>
   <td>密&nbsp;&nbsp;码:</td>
   <td><input type="password" name="password" id="password" onchange="return check_password() == true"></td>
   <td></td>
   <td><div id="display_password" class="display"></div></td>
   </tr>
   <tr>
   <td>验证码:</td>
   <td><input type="text" name="certCode" maxlength="4" id="certCode" onchange="return check_certCode()==true;"></td>
   <td><img src="makeCertPic.jsp" id="img" title="refresh" name="img">
   <a href="JavaScript:reLoadImg();">换一张</a></td>
   <td><div id="display_certCode" class="display"></div></td>
   </tr>
   <tr><td></td><td></td>
   <td><font size="4"><input type="submit" value="登陆"></font></td></tr>
   </table>
    </form>
    </div>
  </body>
</html>
生成验证码图片:makeCertPic.jsp
<%@page contentType="image/jpeg" %>
<jsp:useBean id="image" scope="page" class="util.makeCertPic" />
<%
String str = image.getCertPic(0,0,response.getOutputStream());
session.setAttribute("certCode", str);
out.clear();//该行及下一行代码可以解决respons.getOutputStream() has already been called 的问题
out = pageContext.pushBody();

%>
生成验证码的类:makeCertPic.java
package util;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
/**
* 生成验证码图片
*/
public class makeCertPic {
    //验证码图片中可以出现的字符集,可根据需要修改
    private char mapTable[]={
    'a','b','c','d','e','f',
    'g','h','i','j','k','l',
    'm','n','o','p','q','r',
    's','t','u','v','w','x',
    'y','z','0','1','2','3',
    '4','5','6','7','8','9'};
    /**
     * 功能:生成彩色验证码图片
     * 参数width为生成的图片的宽度,参数height为生成的图片的高度,参数os为页面的输出流
     */
    public String getCertPic(int width, int height, OutputStream os) {
if(width<=0)width=60;
if(height<=0)height=20;
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
// 获取图形上下文
Graphics g = image.getGraphics();
// 设定背景色
g.setColor(new Color(0xDCDCDC));
g.fillRect(0, 0, width, height);
//画边框
g.setColor(Color.black);
g.drawRect(0,0,width-1,height-1);
// 取随机产生的认证码
String strEnsure = "";
// 4代表4位验证码,如果要生成更多位的认证码,则加大数值
for(int i=0; i<4; ++i) {
strEnsure += mapTable[(int)(mapTable.length*Math.random())];
}
// 将认证码显示到图象中,如果要生成更多位的认证码,增加drawString语句
g.setColor(Color.black);
g.setFont(new Font("Atlantic Inline",Font.PLAIN,18));
String str = strEnsure.substring(0,1);
g.drawString(str,8,17);
str = strEnsure.substring(1,2);
g.drawString(str,20,15);
str = strEnsure.substring(2,3);
g.drawString(str,35,18);
str = strEnsure.substring(3,4);
g.drawString(str,45,15);
// 随机产生10个干扰点
Random rand = new Random();
for (int i=0;i<10;i++) {
int x = rand.nextInt(width);
int y = rand.nextInt(height);
g.drawOval(x,y,1,1);
}
// 释放图形上下文
g.dispose();
try {
// 输出图象到页面
ImageIO.write(image, "JPEG", os);
os.flush(); 
os.close(); 
os=null;
} catch (IOException e) {
return "";
}
return strEnsure;
}
}
以上代码网上有很多,但是要实现验证码图片的刷新及验证就需要用到以下的JS
Check_login.js
function check_username()
  {
  var v = new Array();
  var username = document.getElementById("username").value;
  //var reg = /[A-Za-z0-9]/;//正则表达式
  var result = username.replace(/(\s+$)|(^\s+)|\s/g,"");//去掉空格
  var reg = /[\u4e00-\u9fa5]|\w/;//用户名可以为中文或英文及数字的组合
  //for(var i = 0; i < username.length; i++)
  //{
  //v[i] = document.getElementById("username").value[i];
  //alert(v[i]);
 
  //}
  if(username.length > 20 || username.length < 4)
  {
  document.getElementById("display_username").innerText = "用户名的长度必须在4到20之间";
  document.getElementById("username").value = "";
  document.getElementById("username").focus();
  return false;
  }
 
  return true;
  }
 
  function check_password()
  {
  var password = document.getElementById("password").value;
  if(password.length > 25 || password.length < 6)
  {
  document.getElementById("display_password").innerText = "密码的长度必须在6到25之间";
  document.getElementById("password").value = "";
  document.getElementById("password").focus();
  return false;
  }
  return true;
  }
 
  //验证码的刷新(这里的刷新是指按换一张后的刷新,但页面本身不会刷新)
  function reLoadImg()
  {
  document.getElementById("img").src = "makeCertPic.jsp?" + Math.random();
  document.getElementById("display_certCode").value = "";
  document.getElementById("certCode").focus();
  }
  //从这里开始实现Ajax的无刷新技术
  var XHR = null;//这里的XHR指的是XMLHttpRequest()的一个对象,但是现在先初始化为空
  function check_certCode()
  {
var certCode = document.getElementById("certCode").value;//先得到用户输入的验证码
  if(window.ActiveXObject)//判断是否为IE浏览器
  {
  XHR = new ActiveXObject("Microsoft.XMLHttpRequest");
  }
  else if(window.XMLHttpRequest)//非IE浏览器
  {
  XHR = new XMLHttpRequest();
  }
 
  if(null != XHR)
  {
  XHR.open("POST","user/checkCertCode.jsp",true);/*为同服务器间通信的对象做准备并初始化,第一个参数表示提交方式(POST或者GET),第二个参数表示提交的URL,第三个表示提交的是异步方式还是同步方式*/
  XHR.onreadystatechange = ajaxRefresh;//将XHR的onreadystatechange事件处理函数赋给函数ajaxRefresh()
//  alert(certCode);
  XHR.setRequestHeader("content-type","application/x-www-form-urlencoded");//post方式的开头
  XHR.send("certCode=" + certCode);//Post方法发送参数,若为GET则为NULL
  }
 
 
  }
 
  function ajaxRefresh()
  {
  if(XHR.readyState == 4)//有1-4可选,1表示加载中,但未调用;2表示已加载,且调用了send方法,但头不可用;3表示交互,已收到部分数据,状态和响应头不可用,4表示完成
  {
  if(XHR.status == 200)//OK
  {
  //alert("oh,yeah");
  }
  else
  if(XHR.status == 404)//服务器找不到URL
  {
  document.getElementById("display_certCode").innerText = "验证码错误,请重新输入";//显示验证信息
  document.getElementById("certCode").value = "";//验证码置空
  document.getElementById("certCode").focus();//焦点返回输入框
  document.getElementById("img").src = "makeCertPic.jsp?" + Math.random();
  //刷新验证码
  }
  }
 
  }
  验证码URL:checkCertCode.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
   
    <title>My JSP 'checkCertCode.jsp' starting page</title>
   
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">   
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->





  </head>
 
  <body>
<%
String certCode = request.getParameter("certCode");
System.out.println(certCode + "---checkCertCode");
System.out.println((String)session.getAttribute("certCode") + "---session");
if(certCode.equals((String)session.getAttribute("certCode")))
{
System.out.println("hello");//成功后没有操作,200
//request.getRequestDispatcher("/user/checkUserLogin.jsp").forward(request, response);
}
else response.sendRedirect("/Error.jsp");//这里的Error.jsp是没有的,即为404


%>




  </body>
</html>