html登录图片验证码的实现

58 篇文章 6 订阅
13 篇文章 0 订阅

流程:验证码图片由服务器的java后端生成,前端向后端请求图片验证码,项目工程使用了springboot框架

生成图片验证码的工具类:

package com.main.activity.verifyCode;


import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;


public class ImageUtil {
    public ImageUtil() {
    }

    public static OutputStream generator(int width, int height, String checkCode) {
        BufferedImage image = new BufferedImage(width, height, 5);
        Graphics g = image.getGraphics();
        Random random = new Random();
        g.setColor(getRandColor(200, 250));
        g.fillRect(0, 0, width, height);
        g.setColor(getRandColor(0, 255));
        g.drawRect(0, 0, width - 1, height - 1);
        g.setColor(getRandColor(160, 200));

        int i;
        int y;
        for (i = 0; i < 8; ++i) {
            i = random.nextInt(width);
            y = random.nextInt(height);
            int x1 = random.nextInt(width);
            int y1 = random.nextInt(height);
            g.drawLine(i, y, x1, y1);
        }

        g.setColor(getRandColor(160, 200));

        for (i = 0; i < 100; ++i) {
            i = random.nextInt(width);
            y = random.nextInt(height);
            g.drawLine(i, y, i, y);
        }

        Font font = new Font("Arial Black", 2, 25);
        g.setFont(font);
        g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));

        for (i = 0; i < checkCode.length(); ++i) {
            g.drawString(String.valueOf(checkCode.charAt(i)), 22 * i + 2, 20);
        }

        g.dispose();
        ByteArrayOutputStream os = new ByteArrayOutputStream();

        try {
            ImageIO.write(image, "jpeg", os);
        } catch (IOException var11) {
            var11.printStackTrace();
        }

        return os;
    }

    private static Color getRandColor(int lower, int upper) {
        Random random = new Random();
        if (upper > 255) {
            upper = 255;
        }

        if (upper < 1) {
            upper = 1;
        }

        if (lower < 1) {
            lower = 1;
        }

        if (lower > 255) {
            lower = 255;
        }

        int r = lower + random.nextInt(upper - lower);
        int g = lower + random.nextInt(upper - lower);
        int b = lower + random.nextInt(upper - lower);
        return new Color(r, g, b);
    }
}

请求验证码图片以及验证码值的controller:

package com.main.activity.verifyCode;

import com.main.dao.DataBaseOP;
import net.sf.json.JSONArray;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.UUID;


@RestController
public class VerifyCodeController {

    /**
     * 去除 l、o、I、O、0、1
     */
    private static final char[] CHAR_ARRAY = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789".toCharArray();
    /**登录图片验证码
     * @param session
     * @return
     */
    @GetMapping("/getVerifyImage")
    public void getVerifyImage(HttpServletRequest request, HttpServletResponse res, HttpSession session) throws IOException {

        String checkCode = RandomStringUtils.random(4, CHAR_ARRAY);

        //TODO 直接返回byte数据
        ByteArrayOutputStream os = (ByteArrayOutputStream) ImageUtil.generator(102, 25, checkCode);
        byte[] bytes = os.toByteArray();
        try {
            os.close();
        } catch (IOException e) {
        }
        session.setAttribute("checkCode", checkCode);//将验证码值存入HttpSession中
        res.setContentType("image/jpg");
        res.setContentLength(bytes.length);
        res.getOutputStream().write(bytes);
    }

    @GetMapping("/getCheckCode")//该方法为验证码值的获取方法
    public Object getCheckCode(HttpSession session) {
        return session.getAttribute("checkCode");
    }

}

前端界面(我的端口号为8099)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    <script>
        var checkCode="";
        function reCheckcode() {
                $("#image").attr({"src":"http://localhost:8099/getVerifyImage?w="+Math.random()});

            document.getElementById("image").onload=function (ev) {
                getCheckCode();
            }
        }

        function getCheckCode(){
            $.get("http://localhost:8099/getCheckCode",function (data) {
            	checkCode=data;
            	console.info(checkCode);
            	return checkCode;
            })
        }
        window.onload=function (ev) { 
            reCheckcode();
        }
    </script>



</head>
<body>

<img id="image" style="height:100%;" title="点击更换验证码"  onclick="reCheckcode()" />
</body>
</html>

在获取验证码值时遇到一个bug:

关于图片验证码刷新问题,要获得新的图片验证码的字符串值,但总是会
    出现问题,获得的验证码是上一次的验证码,不是新的验证码,查找错误后
    发现原因是向后台请求验证码图片并且前台加载验证码都需要一定的时间,
    而我的向后台获取验证码值的执行速度较快,所以导致获得的验证码值总是上一次
    的验证码值。
    解决方法:
    1.使用setTimeout方法,在刷新验证码后的500ms再执行该获得验证码值的方法
    eg:setTimeout(getCheckCode,500);
    2.使用html元素image的onload方法,即当图片加载完成后再进行获取验证码的操作,
    eg:document.getElementById("image").οnlοad=function (ev) {
                    getCheckCode();
                };
    (其中getCheckCode()是获得验证码值的方法)

参考博客:

https://blog.csdn.net/jiahao1186/article/details/82501009

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值