一只不睡觉的水壶 2025-01-24 00:11 采纳率: 86.2%
浏览 22
已结题

为什么前端验证码没办法正确显示

为什么我javaweb前端验证码这块无法显示图片,就是这种验证码图片出现立即消失并显示替代文本,点击它也是立即出现然后替代文本,想问一下怎么解决,比较急。
这是我的util包中的制作验证码图片的代码

package com.example.myproject.utils;

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

public class VerifyCode {
    private int w = 100;
    private int h = 40;
    private Random r = new Random();
    // {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"}
    private String[] fontNames =
            { "宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312" };
    // 可选字符
    private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
    // 背景色
    private Color bgColor = new Color(255, 255, 255);
    // 验证码上的文本
    private String text;

    // 生成随机的颜色
    private Color randomColor() {
        int red = r.nextInt(150);
        int green = r.nextInt(150);
        int blue = r.nextInt(150);
        return new Color(red, green, blue);
    }

    // 生成随机的字体
    private Font randomFont() {
        int index = r.nextInt(fontNames.length);
        String fontName = fontNames[index];// 生成随机的字体名称
        int style = r.nextInt(4);// 生成随机的样式, 0(无样式), 1(粗体), 2(斜体), 3(粗体+斜体)
        int size = r.nextInt(5) + 24; // 生成随机字号, 24 ~ 28
        return new Font(fontName, style, size);
    }

    // 画干扰线
    private void drawLine(BufferedImage image) {
        int num = 3;// 一共画3条
        Graphics2D g2 = (Graphics2D) image.getGraphics();
        for (int i = 0; i < num; i++) {// 生成两个点的坐标,即4个值
            int x1 = r.nextInt(w);
            int y1 = r.nextInt(h);
            int x2 = r.nextInt(w);
            int y2 = r.nextInt(h);
            g2.setStroke(new BasicStroke(1.5F));
            g2.setColor(Color.BLUE); // 干扰线是蓝色
            g2.drawLine(x1, y1, x2, y2);// 画线
        }
    }

    // 随机生成一个字符
    private char randomChar() {
        int index = r.nextInt(codes.length());
        return codes.charAt(index);
    }

    // 创建BufferedImage
    private BufferedImage createImage() {
        BufferedImage image = new BufferedImage(w, h,
                BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = (Graphics2D) image.getGraphics();
        g2.setColor(this.bgColor);
        g2.fillRect(0, 0, w, h);
        return image;
    }

    // !调用这个方法得到验证码
    public BufferedImage getImage() {
        BufferedImage image = createImage();// 创建图片缓冲区
        Graphics2D g2 = (Graphics2D) image.getGraphics();// 得到绘制环境
        StringBuilder sb = new StringBuilder();// 用来装载生成的验证码文本
        // 向图片中画4个字符
        for (int i = 0; i < 4; i++) {// 循环四次,每次生成一个字符
            String s = randomChar() + "";// 随机生成一个字母
            sb.append(s); // 把字母添加到sb中
            float x = i * 1.0F * w / 4; // 设置当前字符的x轴坐标
            g2.setFont(randomFont()); // 设置随机字体
            g2.setColor(randomColor()); // 设置随机颜色
            g2.drawString(s, x, h - 5); // 画图
        }
        this.text = sb.toString(); // 把生成的字符串赋给了this.text
        drawLine(image); // 添加干扰线
        return image;
    }

    // 返回验证码图片上的文本
    public String getText() {
        return text;
    }

    // 保存图片到指定的输出流
    public static void output(BufferedImage image, OutputStream out)
            throws IOException {
        ImageIO.write(image, "JPEG", out);
    }
}

这是我响应这块

package com.example.myproject.controller;

import com.example.myproject.service.Userservse;
import com.example.myproject.utils.VerifyCode;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;

@RestController
@RequestMapping("/api")
public class CaptchaController {
    private final VerifyCode verifyCode = new VerifyCode();
    @Autowired
    private Userservse userservse;

    @GetMapping("/captcha")
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
        BufferedImage captchaImage = verifyCode.getImage();
        response.setContentType("image/jpeg");
        ImageIO.write(captchaImage, "jpeg", response.getOutputStream());
        HttpSession session=request.getSession();
        session.setAttribute("captcha", verifyCode.getText());
    }

    @RequestMapping("forgetit")
    public String forgetit(String userPhone,String newpassword,String recognise, Model model, HttpSession session)
    {
        String sessionCaptcha = (String) session.getAttribute("captcha");
        if(recognise.equals(sessionCaptcha))
        {
            model.addAttribute("error", "验证码错误");
            return "index";
        }
        else
        {
            boolean userExists = userservse.forgott(userPhone);
            if(userExists)
            {
                userservse.renew(newpassword,userPhone);
                return "index";
            }

            else
            {
                model.addAttribute("error", "不存在此电话号码");
                return "forgetPassword";
            }
        }

    }



}


这是我的前端代码


```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>忘记密码</title>
    <link rel="stylesheet" type="text/css" href="../static/forget.css">
    <link rel="stylesheet" type="text/css" href="../static/fontawesome-free-6.7.2-web">
</head>
<body>
    <div class="head1">
        <h1>
            修养生息——为年轻人创造的养生服务平台
        </h1>
    </div>
    <div class="containerr">
        <div class="log_intext">
            <h1>
                忘记密码
            </h1>
        </div>

        <div class="log_in">
            <form th:action="@{/forgetit}" th:method="post">
                <span>
                    <i class="fa-solid fa-phone"></i>
                    <input type="text" placeholder="请输入手机号码" name="userPhone">
                </span>
                <br>
                <span>
                    <i class="fa-solid fa-user"></i>
                    <input type="text" placeholder="请输入新密码" name="newpassword">
                </span>
                <br>
                <span class="input-with-captcha">
                    <input type="text" class="half-width" placeholder="请输入验证码" name="recognise">
                    <img src="/api/captcha" alt="验证码" class="captcha-image" onclick="this.src='/api/captcha?'+Math.random();">
                </span>
                <br>
                <button>提交</button>
            </form>
        </div>
        <div class="elsesetiong">
            <label>
                <a th:href="@{/tolog_in}" style="margin-right: 140px;">
                    返回登录
                </a>
                <a th:href="@{/toRegister}" >
                    注册账号
                </a>
            </label>
        </div>
    </div>

</body>
</html>



body{
    width: 1200px;
    margin: 0 auto;
    background-image:url(/static/log_inbackground.png);
    background-repeat: no-repeat;
    background-size: cover;
    overflow:hidden;
}
.head1 h1
{
    display: flex;
    background-color: transparent;
    font-size: 40px;
    font-family: "华文新魏";
    color: forestgreen;
    margin: 20px 0px 0px;
    justify-content: center;
    overflow: hidden;
}
.containerr
{
    width: 300px;
    margin: 7% auto;
    border-radius: 25px;
    background-color: rgba(0,0,0,0.1);
    box-shadow: 0 0 17px #333;
}
.log_intext
{
    text-align: center;
    padding-top: 75px;
    padding-bottom: 60px;
    font-family: "华文新魏";
    color: #006400;
}
.log_in
{
    padding-left: 45px;

}
.log_in button,input
{
    width: 200px;
    height: 40px;
    border: none;
    outline: none;
    padding-left: 40px;
    box-sizing: border-box;
    font-size: 15px;
    color: #333;
    margin-bottom: 20px;
}
.log_in button
{
    padding-left: 0;
    background-color: #83acf1;
    letter-spacing: 1px;
    font-weight: bold;
    margin-bottom: 50px;
    margin-top: 20px;
    border-radius:10px;
}
.log_in button:hover
{
    box-shadow: 2px 2px 5px #555;
    background-color: #7799d4;
}
.log_in input:hover
{
    box-shadow: 2px 2px 5px #555;
    background-color: #ddd;
}

.log_in span
{
    position:relative;
}
.log_in i
{
    position: absolute;
    left:15px;
    color:#333;
    font-size: 16px;
    top:2px;
}
.elsesetiong
{
    padding-bottom: 10px;
    padding-left: 10px;
}
.elsesetiong a
{
    text-decoration: none;
    color: #555555;
}
.half-width
 {
     padding: 0;
     width:100px;
     text-align: left;
     margin-left: 0;
     margin-right: 0;
 }
.input-with-captcha {
    display: flex;
    align-items: center; /* 垂直居中 */
}
.input-with-captcha input {
    /* 这里可以保留.half-width类的样式,或者根据需要调整 */
    /* 让输入框占据剩余空间 */
    margin-right: 10px; /* 输入框和图片之间的间距 */
}
.captcha-image {
    padding: 0;
    width:100px;
    text-align: left;
    margin-left: 0;
    margin-right: 0;
    height: 40px;
    overflow: hidden;/* 根据需要调整图片高度,与输入框高度相匹配 */
     /* 根据图片原始比例调整宽度 */
}


  • 写回答

4条回答 默认 最新

  • 关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    根据您提供的代码和描述,您的验证码显示后消失并出现替代文本的问题可能与您的前端JavaScript代码有关。在这种情况下,一种可能的问题是图片URL没有正确地设置。下面是解决这个问题的步骤和注意事项:

    前端响应问题:前端应该在点击验证码图片时刷新图片的URL,而不是重新加载整个页面。这样,验证码图片就可以更新,而不是简单地重新加载同样的图像,此时其文本应该是之前已保存的验证码文字(服务器设置的一个Session属性)。在这个场景中,验证码图片被点击后,服务器应该生成一个新的验证码并返回新的图片。由于您已经在前端代码中实现了点击验证码图片后刷新图片的功能(使用了onclick事件),这是正确的做法。

    服务器端问题:服务器应该正确地处理来自前端的请求并返回新的验证码图片。在您的代码中,看起来服务器已经正确地处理了请求并返回了验证码图片。然而,如果服务器在处理请求时遇到任何问题(例如数据库连接问题或内存溢出),它可能会返回一个错误响应,导致前端显示替代文本。您需要检查服务器的日志以确定是否存在任何错误或异常。此外,确保服务器正确地设置了响应的Content-Type为image/jpeg。这样前端就能正确地识别这是一个图片资源而不是一个普通的文本资源。您已经在代码中实现了这一点。另外要确保验证码图片的URL正确生成,没有发生路径错误或路由问题导致的图片加载失败。如果URL不正确,浏览器会尝试加载一个不存在的资源,这会导致替代文本的显示。确保URL指向正确的资源路径和正确的控制器方法。最后,确保服务器端的验证码生成逻辑没有问题,能够正确生成验证码图片并返回给前端。如果服务器端出现问题,即使前端代码没有问题也无法正确显示验证码图片。如果您无法确定问题的原因,您可以尝试检查服务器端的日志信息以获取更多关于问题的信息。如果你还无法找到问题的根源,建议你从简单开始一步一步进行排查:例如尝试暂时禁用所有的安全性检查或设置相关的超时等以确保请求能被成功处理等等。在找到问题之后可以尝试恢复这些设置并进行必要的调整以满足实际需求和安全要求。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 2月1日
  • 已采纳回答 1月24日
  • 创建了问题 1月24日