springboot+ajax+验证码 分手后的思念是犯贱 2023-06-29 06:00 32阅读 0赞 ### 一.效果 ### ![!\[\](https://img-blog.csdnimg.cn/2020011102053397.png?x-oss-process=image/watermark,type\_ZmFuZ3poZW5naGVpdGk,shadow\_10,text\_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1NDUzMjY2,size\_16,color\_FFFFFF,t\_70][https_img-blog.csdnimg.cn_2020011102053397.png_x-oss-process_image_watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1NDUzMjY2_size_16_color_FFFFFF_t_70] ### 二.整体流程 ### ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1NDUzMjY2_size_16_color_FFFFFF_t_70] ### 三.详细代码 ### #### 前端: #### **1.发起ajax请求获取验证码图片,拿到图片src后动态刷新.** function getVerifyCode() { $.ajax({ url: URL + '/api/admin/code/', type: 'GET', data: { width: 180, //验证码图片的高 height: 50, //验证码图片的宽 }, xhrFields: { withCredentials: true //前后端分离项目为解决跨域的问题必须这样设置 }, success: function (result) { var image = result.data.img; recordId = result.data.recordId; if (image != null && recordId != null) { $("#verify-code").attr("src", URL + image + ".png"); //动态刷新验证码图片 $.cookie('recordId', recordId, { expires: 7, path: '/'}); //将验证码唯一标识recordId保存在cookie } } }); } **2.点击刷新按钮,再次获取验证码图片** function paperEvent() { $("#refresh").click(function () { getVerifyCode(); }); } #### 后端: #### **1.生成验证码工具类:** package com.selenium.sdjubbs.common.util; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; /** * 随机生成验证码 * * @author selenium * */ public class VerifyCodeUtil { public static String drawVerifyCode(int width, int height,String savePath,String imageName) throws IOException { StringBuffer verifyCode = new StringBuffer(); Random random = new Random(); BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Font font = new Font("微软雅黑", Font.BOLD, 40); int degree = random.nextInt() % 30; // 旋转角度小于30度 int x = 10; // 旋转原点的 x 坐标 int ROTATE_Y = 45;// 旋转原点的 y 坐标 Graphics2D graphics = bufferedImage.createGraphics(); graphics.setColor(Color.WHITE);// 设置画笔颜色,也是验证码的背景色 graphics.fillRect(0, 0, width, height); graphics.setFont(font); // 绘制验证码 for (int i = 0; i < 4; i++) { graphics.setColor(getRandomColor()); // 正向旋转 graphics.rotate(degree * Math.PI / 180, x, ROTATE_Y); String ch = getRandomChar(); verifyCode.append(ch); graphics.drawString(ch, x, ROTATE_Y); // 反向旋转 graphics.rotate(-degree * Math.PI / 180, x, ROTATE_Y); x += 48; } // 画干扰线 for (int i = 0; i < 6; i++) { graphics.setColor(getRandomColor()); graphics.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height)); } // 添加噪点 for (int i = 0; i < 30; i++) { graphics.setColor(getRandomColor()); int x1 = random.nextInt(width); int y1 = random.nextInt(height); graphics.fillRect(x1, y1, 2, 2); } File dir =new File(savePath); if(!dir.exists()) { dir.mkdirs(); } ImageIO.write(bufferedImage, "png",new File(savePath+File.separator+imageName+".png")); return verifyCode.toString(); } /** * 随机取色 */ private static Color getRandomColor() { Random random = new Random(); Color color = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256)); return color; } /** * 随机生成每个验证码 * * @return */ private static String getRandomChar() { String baseString = "123456789abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"; Random random = new Random(); String ch = baseString.charAt(random.nextInt(baseString.length())) + ""; return ch; } } **2.验证码后端业务逻辑处理** @GetMapping(Api.VERIFY_CODE) public Result getVerifyCode(int width, int height, HttpServletRequest request) { //根据ip作为用户标识,进行md5加密后取前10位,加密是因为图片名会用到ip,不直接暴露路径 String ip = MD5Util.md5(request.getRemoteAddr()).substring(0, 10); String imagePath = "/common/" + setting.getVerifyCodeSavePath().split("/common/")[1]; //验证码的存储路径为 项目在系统中的绝对路径/相对于项目的存储路径/ String savePath = System.getProperty("user.dir") + setting.getVerifyCodeSavePath(); //验证码存储图片名:ip_时间戳 String imageName = ip + "_" + System.currentTimeMillis(); //1.如果此ip之前有产生验证码图片,先删除之前产生的验证码图片,防止用户不停点击刷新,不停创建验证码图片 // 消耗内存. //2.每次产生的验证码图片名都应该不一样,不能直接覆盖,不然点击刷新后,后端图片发生了变化,但前端 // 却还是显示的之前的验证码图片 FileUtil.deleteFilesWithPrefix(savePath, ip); String verifyCode = ""; String recordId = ""; String verifyCodeKey = ""; try { verifyCode = VerifyCodeUtil.drawVerifyCode(width, height, savePath, imageName); //验证码的唯一标识符recordId recordId = System.currentTimeMillis() + UUID.randomUUID().toString(); //存入redis中的key verifyCodeKey = "verifycode:" + ip + ":" + recordId; //60秒后验证码失效 redisService.set(verifyCodeKey, verifyCode, 60); } catch (IOException e) { e.printStackTrace(); } //将图片路径和唯一标识符recordId返回给前端 return Result.success().add("img", imagePath + "/" + imageName).add("recordId", recordId); } ### 出现的一些问题: ### **1.Springboot项目中验证码图片生成后,直接访问不到图片.** 图片存储的路径(C:\\src\\idea\\SDJUBBS\\src\\main\\resources\\static\\common\\images\\verifycode\\xxx.png) 图片访问的路径(http://localhost:8080/common/images/verifycode/xxx.png) 原因是因为tomcat对于静态资源有保护的措施,需要我们通过程序,将访问路径映射到实际的路径 package com.selenium.sdjubbs.common.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class ResourceConfig extends WebMvcConfigurerAdapter { @Autowired private SdjubbsSetting setting; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { //前面是映射后的地址,后面是需要映射的地址 //获取文件的真实路径 String path = System.getProperty("user.dir") + setting.getBaseDirSavePath(); System.out.println(path); registry.addResourceHandler("/common/**"). addResourceLocations("file:" + path); super.addResourceHandlers(registry); } } [https_img-blog.csdnimg.cn_2020011102053397.png_x-oss-process_image_watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1NDUzMjY2_size_16_color_FFFFFF_t_70]: https://img-blog.csdnimg.cn/20200111020636165.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1NDUzMjY2,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1NDUzMjY2_size_16_color_FFFFFF_t_70]: https://img-blog.csdnimg.cn/2020011102121849.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1NDUzMjY2,size_16,color_FFFFFF,t_70
相关 验证码 package com.cyparty.laihui.utilities; import javax.imageio.ImageIO; imp 拼搏现实的明天。/ 2023年10月06日 12:00/ 0 赞/ 31 阅读
相关 验证码 验证码的验证是我们登陆网页时经常进行的操作,我也做了一个简单的验证码,包括颜色以及噪线等等 @RequestMapping(value = "/Frame/Verif r囧r小猫/ 2022年07月16日 08:28/ 0 赞/ 248 阅读
相关 验证码 1、需求 在访问登录页面时,需要生产验证码。从而防止用户使用程序恶意登录。 2、代码实现 步骤1:修改登录页面,确定验证码图片显示的位置 ! 柔光的暖阳◎/ 2022年03月21日 16:10/ 0 赞/ 279 阅读
相关 tp5 验证码验证 验证码刷新 首先使用`Composer`安装`think-captcha`扩展包: composer require topthink/think-captcha 在控制器中使 我会带着你远行/ 2022年02月23日 14:16/ 0 赞/ 370 阅读
相关 验证码 验证码 google验证码kaptcha Java验证码 patchca 验证码工具类 google验证码kaptcha [https://bl 女爷i/ 2022年02月15日 09:30/ 0 赞/ 315 阅读
相关 验证码---短信验证码 最近自学了短信的验证码实现。以下是自己用的一种方法实现的完整的过程。 短信验证登陆(前端+后台) 1、前端填写手机号以及点击触发,以电话号码为参数调用发送验证登录短信方法并 青旅半醒/ 2022年01月09日 08:53/ 0 赞/ 656 阅读
相关 验证码 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ub ╰半橙微兮°/ 2021年12月23日 13:47/ 0 赞/ 383 阅读
相关 验证码 <% @ WebHandler Language = " C\ " Class = " code " %> using System; using 亦凉/ 2021年11月24日 01:36/ 0 赞/ 379 阅读
相关 【验证码】PHP生成随机验证码 <?php // Header("Content-type: image/gif"); / 初始化 / $bo 本是古典 何须时尚/ 2021年09月26日 02:36/ 0 赞/ 604 阅读
相关 验证码 js <img id="validateCode\_img" src="/handerashx/VerifyCode.ashx" width="90" height=" 比眉伴天荒/ 2021年09月11日 04:12/ 0 赞/ 473 阅读
还没有评论,来说两句吧...