zoukankan      html  css  js  c++  java
  • 前端ajax+模态框,快速请求服务器获取验证码图片,怎么保证图片的快速刷新并且正常显示,不会有缓存呢?

    下面我举的例子是,前端通过ajax+bootstrap的模态框,向服务器获取验证码图片。

    效果:

    如何实现呢?

    1、第一种:

    一般向服务器请求图片时,都是将图片保存在服务器上,再将网络地址URL返回,前端通过URL获取图片。

    前端代码:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ include file="/resources/base/taglib.jsp"%>
    <html>
    <head>
        <title>Title</title>
        <script src="<c:url value='/resources/YQQ/js/jquery-3.1.0.min.js'/>"></script>
        <script src="<c:url value='/resources/YQQ/js/bootstrap.min.js'/>"></script>
        <link href="<c:url value='/resources/YQQ/css/bootstrap.min.css'/>" rel="stylesheet">
    </head>
    <body>
    
        <button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal" onclick="getCode()">
            获取验证码
        </button>
        <!-- 模态框(Modal) -->
        <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal"
                                aria-hidden="true">×
                        </button>
                        <h4 class="modal-title" id="myModalLabel">
                            请输入验证码:
                        </h4>
                    </div>
                    <div class="modal-body">
                        <img src="" id="code">
                        <input type="text" id="codeText">
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default"
                                data-dismiss="modal">关闭
                        </button>
                        <button type="button" class="btn btn-primary" onclick="mnLogin()">
                            提交
                        </button>
                    </div>
                </div><!-- /.modal-content -->
            </div><!-- /.modal-dialog -->
        </div><!-- /.modal -->
    
    </body>
    <script>
        function getCode() {
            $("#code").attr("src", "");
            $.ajax({
                url: '${base}/bbm/getCode',
                type: "post",
                success: function (data) {
                    setTimeout(function(){}, 500);
                    $("#code").attr("src", data);
                }
            })
        }</script>
    </html>

    后端代码

    @ResponseBody
    @RequestMapping("getCode")
    public String getCode(HttpServletRequest request){
        System.out.println("====");
        try {
            String imgURLPath = TestLogin.getCode(request);
            return imgURLPath;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }
    // 将验证码图片保存到服务器,并返回url访问地址
    public static String getCode(HttpServletRequest request) throws IOException {
    /*这一段是请求接口,获取验证码的图片*/
        HttpGet get = new HttpGet("xxxx");
        // 创建一个http客户端
        CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultCookieStore(COOKIE).build();
        // 发送get请求
        HttpResponse response = httpClient.execute(get);
        byte[] bytes = EntityUtils.toByteArray(response.getEntity());
    /*这一段是请求接口,获取验证码的图片*/
    
        // 文件存放路径
        String realPath = request.getServletContext().getRealPath("/resources");
        // 文件名称 code.jpg
        String fileName = "code.jpg";
        // 文件输出
        File file = new File(realPath, fileName);
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        fileOutputStream.write(bytes);
        fileOutputStream.close();
    
        String urlPath = request.getScheme() + "://" +
                request.getServerName() + ":" +
                request.getServerPort() + request.getContextPath() + "/resources/" + fileName;
        return urlPath;
    }

    第一种方式,存在的问题:

    1)第一次访问验证码没有问题,但是关闭模态框后,再次点开发现验证码并没有发生改变,而服务器上保存的图片却改变了。

    解决方法: 

    只需要在请求验证码图片的url后面加入不同的参数,保证浏览器不会因为请求地址url相同,而直接从缓存中读取。

    $("#code").attr("src", data + "?datetime=" + new Date().getTime() + Math.round(Math.random()*100));

    2)但是修改之后,又出现新的问题:请求过快导致图片无法正常显示,并且不能够保证浏览器还是会从缓存中读取图片。

    2、第二种:

    因为将图片保存到服务器时,由于网络的原因有时候会慢,所以前端访问的时候,可能图片还没有保存到服务器,而导致图片无法正常显示。

    解决方式:先将图片转为byte字节数组,再转为base64编码的字符串,传递给前端,前端显示显示出来即可。

    为什么要使用base64编码的图片?

    可以减少http请求,一个请求相当于一个网络开销。第一种方式,还需要再次发起http请求。

    后端代码

    @ResponseBody
    @RequestMapping("getCode")
    public String getCode(HttpServletRequest request){
        try {
            byte[] codeBytes = TestLogin.getCodeBytes();
            //定义一个BASE64Encoder
            BASE64Encoder encode = new BASE64Encoder();
            //将byte[]转换为base64
            String base64 = encode.encode(codeBytes);
            return base64;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    前端代码

    function getCode() {
        $("#code").attr("src", "");
        $.ajax({
            url: '${base}/bbm/getCode',
            type: "post",
            success: function (data) {
                if (data!=null){
                    str = 'data:image/png;base64,' + data;
                    $("#code").attr("src", str);
                }else{
                    alert("错误");
                }
            }
        })
    }

     这样的话,无论关闭模态框 / 显示模态框,点击多快,都不会出现验证码图片显示不正常的请求,也保证每次的验证码都是不同的。

    致力于记录学习过程中的笔记,希望大家有所帮助(*^▽^*)!
  • 相关阅读:
    Android--Facebook Login with LoginButton
    Android--Bitmap处理、圆角、圆形
    Android--打开指定程序(微博/微信/QQ等)
    Android--Google Map API V2使用
    关于Reportviewer
    Oracle Clob使用
    ASPNET WebForm T1453工作记录
    Oracle脚本批量导入时,输出日志文件
    Easyui DataGrid Editor
    Oracle 更改数据2中方式差异
  • 原文地址:https://www.cnblogs.com/zxhbk/p/13292215.html
Copyright © 2011-2022 走看看