1. 程式人生 > 實用技巧 >前端ajax+模態框,快速請求伺服器獲取驗證碼圖片,怎麼保證圖片的快速重新整理並且正常顯示,不會有快取呢?

前端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("錯誤");
            }
        }
    })
}

這樣的話,無論關閉模態框 / 顯示模態框,點選多快,都不會出現驗證碼圖片顯示不正常的請求,也保證每次的驗證碼都是不同的。