浅谈用jQuery实现无刷新验证码

开发 后端
本文将介绍如何用jQuery实现无刷新验证码,这也是网页设计过程中比较重要的环节,主要是遏制自动发帖机对网站的恶意损害。

1.思路:

页面上的验证码图片是servlet,采用jquery实现异步校验信息

2.所用到的文件

VerifyCodeServlet.java   --用于生成图片的servlet

ResultServlet.java          --用于校验验证码正确性的servlet

verifyCode.js                  --校验的js文件

jquery.js                         --jquery包里的源文件

verifyCode.jsp                --页面

3.代码

  1. VerifyCodeServlet.java   
  2.  
  3. Java代码   
  4. import java.awt.Color;         
  5. import java.awt.Font;         
  6. import java.awt.Graphics2D;         
  7. import java.awt.image.BufferedImage;         
  8. import java.util.Random;         
  9.         
  10. import javax.imageio.ImageIO;         
  11. import javax.servlet.ServletException;         
  12. import javax.servlet.ServletOutputStream;         
  13. import javax.servlet.http.HttpServlet;         
  14. import javax.servlet.http.HttpServletRequest;         
  15. import javax.servlet.http.HttpServletResponse;         
  16. import javax.servlet.http.HttpSession;         
  17.         
  18. public class VerifyCodeServlet extends HttpServlet {         
  19.         
  20.     // 验证码图片的宽度。         
  21.     private int width = 60;         
  22.         
  23.     // 验证码图片的高度。         
  24.     private int height = 20;         
  25.         
  26.     // 验证码字符个数         
  27.     private int codeCount = 4;         
  28.         
  29.     private int x = 0;         
  30.         
  31.     // 字体高度         
  32.     private int fontHeight;         
  33.         
  34.     private int codeY;         
  35.         
  36.     char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',         
  37.             'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',         
  38.             'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };         
  39.         
  40.     /**       
  41.      * 初始化验证图片属性       
  42.      */        
  43.     public void init() throws ServletException {         
  44.         // 从web.xml中获取初始信息         
  45.         // 宽度         
  46.         String strWidth = this.getInitParameter("width");         
  47.         // 高度         
  48.         String strHeight = this.getInitParameter("height");         
  49.         // 字符个数         
  50.         String strCodeCount = this.getInitParameter("codeCount");         
  51.         
  52.         // 将配置的信息转换成数值         
  53.         try {         
  54.             if (strWidth != null && strWidth.length() != 0) {         
  55.                 width = Integer.parseInt(strWidth);         
  56.             }         
  57.             if (strHeight != null && strHeight.length() != 0) {         
  58.                 height = Integer.parseInt(strHeight);         
  59.             }         
  60.             if (strCodeCount != null && strCodeCount.length() != 0) {         
  61.                 codeCount = Integer.parseInt(strCodeCount);         
  62.             }         
  63.         } catch (NumberFormatException e) {         
  64.         }         
  65.         
  66.         x = width / (codeCount + 1);         
  67.         fontHeight = height - 2;         
  68.         codeY = height - 4;         
  69.         
  70.     }         
  71.         
  72.     protected void service(HttpServletRequest req, HttpServletResponse resp)         
  73.             throws ServletException, java.io.IOException {         
  74.         
  75.         // 定义图像buffer         
  76.         BufferedImage buffImg = new BufferedImage(width, height,         
  77.                 BufferedImage.TYPE_INT_RGB);         
  78.         Graphics2D g = buffImg.createGraphics();         
  79.         
  80.         // 创建一个随机数生成器类         
  81.         Random random = new Random();         
  82.         
  83.         // 将图像填充为白色         
  84.         g.setColor(Color.WHITE);         
  85.         g.fillRect(0, 0, width, height);         
  86.         
  87.         // 创建字体,字体的大小应该根据图片的高度来定。         
  88.         Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);         
  89.         // 设置字体。         
  90.         g.setFont(font);         
  91.         
  92.         // 画边框。         
  93.         g.setColor(Color.BLACK);         
  94.         g.drawRect(0, 0, width - 1, height - 1);         
  95.         
  96.         // 随机产生160条干扰线,使图象中的认证码不易被其它程序探测到。         
  97.         g.setColor(Color.BLACK);         
  98.         for (int i = 0; i < 160; i++) {         
  99.             int x = random.nextInt(width);         
  100.             int y = random.nextInt(height);         
  101.             int xl = random.nextInt(12);         
  102.             int yl = random.nextInt(12);         
  103.             g.drawLine(x, y, x + xl, y + yl);         
  104.         }         
  105.         
  106.         // randomCode用于保存随机产生的验证码,以便用户登录后进行验证。         
  107.         StringBuffer randomCode = new StringBuffer();         
  108.         int red = 0green = 0blue = 0;         
  109.         
  110.         // 随机产生codeCount数字的验证码。         
  111.         for (int i = 0; i < codeCount; i++) {         
  112.             // 得到随机产生的验证码数字。         
  113.             String strRand = String.valueOf(codeSequence[random.nextInt(36)]);         
  114.             // 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。         
  115.             red = random.nextInt(255);         
  116.             green = random.nextInt(255);         
  117.             blue = random.nextInt(255);         
  118.         
  119.             // 用随机产生的颜色将验证码绘制到图像中。         
  120.             g.setColor(new Color(red, green, blue));         
  121.             g.drawString(strRand, (i + 1) * x, codeY);         
  122.         
  123.             // 将产生的四个随机数组合在一起。         
  124.             randomCode.append(strRand);         
  125.         }         
  126.         // 将四位数字的验证码保存到Session中。         
  127.         HttpSession session = req.getSession();         
  128.         session.setAttribute("validateCode", randomCode.toString());         
  129.         
  130.         // 禁止图像缓存。         
  131.         resp.setHeader("Pragma", "no-cache");         
  132.         resp.setHeader("Cache-Control", "no-cache");         
  133.         resp.setDateHeader("Expires", 0);         
  134.         
  135.         resp.setContentType("image/jpeg");         
  136.         
  137.         // 将图像输出到Servlet输出流中。         
  138.         ServletOutputStream sos = resp.getOutputStream();         
  139.         ImageIO.write(buffImg, "jpeg", sos);         
  140.         sos.close();         
  141.     }         
  142.         
  143. }      
  144. import java.awt.Color;      
  145. import java.awt.Font;      
  146. import java.awt.Graphics2D;      
  147. import java.awt.image.BufferedImage;      
  148. import java.util.Random;      
  149.      
  150. import javax.imageio.ImageIO;      
  151. import javax.servlet.ServletException;      
  152. import javax.servlet.ServletOutputStream;      
  153. import javax.servlet.http.HttpServlet;      
  154. import javax.servlet.http.HttpServletRequest;      
  155. import javax.servlet.http.HttpServletResponse;      
  156. import javax.servlet.http.HttpSession;      
  157.      
  158. public class VerifyCodeServlet extends HttpServlet {      
  159.      
  160.     // 验证码图片的宽度。      
  161.     private int width = 60;      
  162.      
  163.     // 验证码图片的高度。      
  164.     private int height = 20;      
  165.      
  166.     // 验证码字符个数      
  167.     private int codeCount = 4;      
  168.      
  169.     private int x = 0;      
  170.      
  171.     // 字体高度      
  172.     private int fontHeight;      
  173.      
  174.     private int codeY;      
  175.      
  176.     char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',      
  177.             'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',      
  178.             'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };      
  179.      
  180.     /**     
  181.      * 初始化验证图片属性     
  182.      */     
  183.     public void init() throws ServletException {      
  184.         // 从web.xml中获取初始信息      
  185.         // 宽度      
  186.         String strWidth = this.getInitParameter("width");      
  187.         // 高度      
  188.         String strHeight = this.getInitParameter("height");      
  189.         // 字符个数      
  190.         String strCodeCount = this.getInitParameter("codeCount");      
  191.      
  192.         // 将配置的信息转换成数值      
  193.         try {      
  194.             if (strWidth != null && strWidth.length() != 0) {      
  195.                 width = Integer.parseInt(strWidth);      
  196.             }      
  197.             if (strHeight != null && strHeight.length() != 0) {      
  198.                 height = Integer.parseInt(strHeight);      
  199.             }      
  200.             if (strCodeCount != null && strCodeCount.length() != 0) {      
  201.                 codeCount = Integer.parseInt(strCodeCount);      
  202.             }      
  203.         } catch (NumberFormatException e) {      
  204.         }      
  205.      
  206.         x = width / (codeCount + 1);      
  207.         fontHeight = height - 2;      
  208.         codeY = height - 4;      
  209.      
  210.     }      
  211.      
  212.     protected void service(HttpServletRequest req, HttpServletResponse resp)      
  213.             throws ServletException, java.io.IOException {      
  214.      
  215.         // 定义图像buffer      
  216.         BufferedImage buffImg = new BufferedImage(width, height,      
  217.                 BufferedImage.TYPE_INT_RGB);      
  218.         Graphics2D g = buffImg.createGraphics();      
  219.      
  220.         // 创建一个随机数生成器类      
  221.         Random random = new Random();      
  222.      
  223.         // 将图像填充为白色      
  224.         g.setColor(Color.WHITE);      
  225.         g.fillRect(0, 0, width, height);      
  226.      
  227.         // 创建字体,字体的大小应该根据图片的高度来定。      
  228.         Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);      
  229.         // 设置字体。      
  230.         g.setFont(font);      
  231.      
  232.         // 画边框。      
  233.         g.setColor(Color.BLACK);      
  234.         g.drawRect(0, 0, width - 1, height - 1);      
  235.      
  236.         // 随机产生160条干扰线,使图象中的认证码不易被其它程序探测到。      
  237.         g.setColor(Color.BLACK);      
  238.         for (int i = 0; i < 160; i++) {      
  239.             int x = random.nextInt(width);      
  240.             int y = random.nextInt(height);      
  241.             int xl = random.nextInt(12);      
  242.             int yl = random.nextInt(12);      
  243.             g.drawLine(x, y, x + xl, y + yl);      
  244.         }      
  245.      
  246.         // randomCode用于保存随机产生的验证码,以便用户登录后进行验证。      
  247.         StringBuffer randomCode = new StringBuffer();      
  248.         int red = 0green = 0blue = 0;      
  249.      
  250.         // 随机产生codeCount数字的验证码。      
  251.         for (int i = 0; i < codeCount; i++) {      
  252.             // 得到随机产生的验证码数字。      
  253.             String strRand = String.valueOf(codeSequence[random.nextInt(36)]);      
  254.             // 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。      
  255.             red = random.nextInt(255);      
  256.             green = random.nextInt(255);      
  257.             blue = random.nextInt(255);      
  258.      
  259.             // 用随机产生的颜色将验证码绘制到图像中。      
  260.             g.setColor(new Color(red, green, blue));      
  261.             g.drawString(strRand, (i + 1) * x, codeY);      
  262.      
  263.             // 将产生的四个随机数组合在一起。      
  264.             randomCode.append(strRand);      
  265.         }      
  266.         // 将四位数字的验证码保存到Session中。      
  267.         HttpSession session = req.getSession();      
  268.         session.setAttribute("validateCode", randomCode.toString());      
  269.      
  270.         // 禁止图像缓存。      
  271.         resp.setHeader("Pragma", "no-cache");      
  272.         resp.setHeader("Cache-Control", "no-cache");      
  273.         resp.setDateHeader("Expires", 0);      
  274.      
  275.         resp.setContentType("image/jpeg");      
  276.      
  277.         // 将图像输出到Servlet输出流中。      
  278.         ServletOutputStream sos = resp.getOutputStream();      
  279.         ImageIO.write(buffImg, "jpeg", sos);      
  280.         sos.close();      
  281.     }      
  282.      
  283. }    
  284.  
  285.  
  286.  
  287.  
  288.  
  289. ResultServlet.java   
  290.  
  291.  
  292. Java代码   
  293. import java.io.IOException;         
  294. import java.io.PrintWriter;         
  295.         
  296. import javax.servlet.ServletException;         
  297. import javax.servlet.http.HttpServlet;         
  298. import javax.servlet.http.HttpServletRequest;         
  299. import javax.servlet.http.HttpServletResponse;         
  300.         
  301. public class ResultServlet extends HttpServlet {         
  302.         
  303.     /**       
  304.      * The doGet method of the servlet. <br>       
  305.      *       
  306.      * This method is called when a form has its tag value method equals to get.       
  307.      *        
  308.      * @param request the request send by the client to the server       
  309.      * @param response the response send by the server to the client       
  310.      * @throws ServletException if an error occurred       
  311.      * @throws IOException if an error occurred       
  312.      */        
  313.     public void doGet(HttpServletRequest request, HttpServletResponse response)         
  314.             throws ServletException, IOException {         
  315.         
  316.         doPost(request, response);         
  317.     }         
  318.         
  319.     /**       
  320.      * The doPost method of the servlet. <br>       
  321.      *       
  322.      * This method is called when a form has its tag value method equals to post.       
  323.      *        
  324.      * @param request the request send by the client to the server       
  325.      * @param response the response send by the server to the client       
  326.      * @throws ServletException if an error occurred       
  327.      * @throws IOException if an error occurred       
  328.      */        
  329.     public void doPost(HttpServletRequest request, HttpServletResponse response)         
  330.             throws ServletException, IOException {         
  331.         
  332.         response.setContentType("text/html;charset=utf-8");         
  333.         String validateC = (String) request.getSession().getAttribute("validateCode");         
  334.         String veryCode = request.getParameter("c");         
  335.         PrintWriter out = response.getWriter();         
  336.         if(veryCode==null||"".equals(veryCode)){         
  337.             out.println("验证码为空");         
  338.         }else{         
  339.             if(validateC.equals(veryCode)){         
  340.                 out.println("验证码正确");         
  341.             }else{         
  342.                 out.println("验证码错误");         
  343.             }         
  344.         }         
  345.         out.flush();         
  346.         out.close();         
  347.     }         
  348.         
  349. }      
  350. import java.io.IOException;      
  351. import java.io.PrintWriter;      
  352.      
  353. import javax.servlet.ServletException;      
  354. import javax.servlet.http.HttpServlet;      
  355. import javax.servlet.http.HttpServletRequest;      
  356. import javax.servlet.http.HttpServletResponse;      
  357.      
  358. public class ResultServlet extends HttpServlet {      
  359.      
  360.     /**     
  361.      * The doGet method of the servlet. <br>     
  362.      *     
  363.      * This method is called when a form has its tag value method equals to get.     
  364.      *      
  365.      * @param request the request send by the client to the server     
  366.      * @param response the response send by the server to the client     
  367.      * @throws ServletException if an error occurred     
  368.      * @throws IOException if an error occurred     
  369.      */     
  370.     public void doGet(HttpServletRequest request, HttpServletResponse response)      
  371.             throws ServletException, IOException {      
  372.      
  373.         doPost(request, response);      
  374.     }      
  375.      
  376.     /**     
  377.      * The doPost method of the servlet. <br>     
  378.      *     
  379.      * This method is called when a form has its tag value method equals to post.     
  380.      *      
  381.      * @param request the request send by the client to the server     
  382.      * @param response the response send by the server to the client     
  383.      * @throws ServletException if an error occurred     
  384.      * @throws IOException if an error occurred     
  385.      */     
  386.     public void doPost(HttpServletRequest request, HttpServletResponse response)      
  387.             throws ServletException, IOException {      
  388.      
  389.         response.setContentType("text/html;charset=utf-8");      
  390.         String validateC = (String) request.getSession().getAttribute("validateCode");      
  391.         String veryCode = request.getParameter("c");      
  392.         PrintWriter out = response.getWriter();      
  393.         if(veryCode==null||"".equals(veryCode)){      
  394.             out.println("验证码为空");      
  395.         }else{      
  396.             if(validateC.equals(veryCode)){      
  397.                 out.println("验证码正确");      
  398.             }else{      
  399.                 out.println("验证码错误");      
  400.             }      
  401.         }      
  402.         out.flush();      
  403.         out.close();      
  404.     }      
  405.      
  406. }    
  407.  
  408.  
  409.  
  410.  
  411.  
  412. verifyCode.js   
  413.  
  414. Java代码   
  415. function changeImg(){     
  416.     var imgSrc = $("#imgObj");     
  417.     var src = imgSrc.attr("src");     
  418.     imgSrc.attr("src",chgUrl(src));     
  419. }     
  420. //时间戳     
  421. //为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳     
  422. function chgUrl(url){     
  423.     var timestamp = (new Date()).valueOf();     
  424.     urlurl = url.substring(0,17);     
  425.     if((url.indexOf("&")>=0)){     
  426.         urlurl = url + "×tamp=" + timestamp;     
  427.     }else{     
  428.         urlurl = url + "?timestamp=" + timestamp;     
  429.     }     
  430.     return url;     
  431. }     
  432.     
  433. function isRightCode(){     
  434.     var code = $("#veryCode").attr("value");     
  435.     code = "c=" + code;     
  436.     $.ajax({     
  437.         type:"POST",     
  438.         url:"resultServlet",     
  439.         data:code,     
  440.         success:callback     
  441.     });     
  442. }     
  443.     
  444. function callback(data){     
  445.     $("#info").html(data);     
  446. }    
  447. function changeImg(){  
  448.  var imgSrc = $("#imgObj");  
  449.  var src = imgSrc.attr("src");  
  450.  imgSrc.attr("src",chgUrl(src));  
  451. }  
  452. //时间戳  
  453. //为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳  
  454. function chgUrl(url){  
  455.  var timestamp = (new Date()).valueOf();  
  456.  urlurl = url.substring(0,17);  
  457.  if((url.indexOf("&")>=0)){  
  458.   urlurl = url + "×tamp=" + timestamp;  
  459.  }else{  
  460.   urlurl = url + "?timestamp=" + timestamp;  
  461.  }  
  462.  return url;  
  463. }  
  464.  
  465. function isRightCode(){  
  466.  var code = $("#veryCode").attr("value");  
  467.  code = "c=" + code;  
  468.  $.ajax({  
  469.   type:"POST",  
  470.   url:"resultServlet",  
  471.   data:code,  
  472.   success:callback  
  473.  });  
  474. }  
  475.  
  476. function callback(data){  
  477.  $("#info").html(data);  
  478. }  
  479.  
  480.  
  481.  
  482. verifyCode.jsp   
  483.  
  484. Java代码   
  485. <%@ page language="java" contentType="text/html; charset=UTF-8"       
  486.     pageEncoding="UTF-8"%>       
  487. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">       
  488. <html>       
  489.     <head>       
  490.         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">       
  491.         <script type="text/javascript" src="js/verifyCode.js"></script>       
  492.         <script type="text/javascript" src="js/jquery.js"></script>       
  493.         <title>test verify code</title>       
  494.     </head>       
  495.     <body>       
  496.         <input id="veryCode" name="veryCode" type="text"/>       
  497.         <img id="imgObj" alt="" src="verifyCodeServlet"/>       
  498.         <a href="#" onclick="changeImg()">换一张</a>       
  499.         <input type="button" value="验证" onclick="isRightCode()"/>       
  500.         <div id="info"></div>       
  501.     </body>       
  502. </html>      
  503. [url]http://www.javaeye.com/post/608953#[/url]   

【编辑推荐】

  1. jQuery调用WCF服务传递JSON对象
  2. 学习jQuery必须知道的几种常用方法
  3. 用XML+XSLT+CSS+JQuery组建ASP.NET网站
  4. 使用jQuery和PHP构建一个受Ajax驱动的Web页面
  5. 使用 jQuery 简化 Ajax 开发
责任编辑:彭凡 来源: javaeye
相关推荐

2017-12-21 07:38:19

2015-09-21 15:31:05

php实现验证码

2021-07-22 10:25:07

JS验证码前端

2009-12-16 15:46:41

Ruby on rai

2024-01-29 08:32:10

Python验证码识别

2013-12-02 15:25:38

jQuery插件

2013-06-19 10:19:59

2009-11-23 16:59:23

PHP图形验证码

2020-09-29 06:43:12

Java

2015-03-23 17:58:04

验证码倒计时并行

2021-01-19 10:29:34

短信验证码密码

2022-02-11 07:10:15

验证码

2020-11-16 07:28:53

验证码

2009-02-09 14:17:36

2009-08-11 14:05:28

JSP验证码

2022-02-02 20:21:24

短信验证码登录

2021-09-02 07:26:27

Django 验证码Framework

2011-11-02 16:46:41

2019-06-18 07:12:25

验证码漏洞加密
点赞
收藏

51CTO技术栈公众号