天天看點

[元件] 1. 驗證碼1. 驗證碼

文章目錄

  • 1. 驗證碼
    • 1. 作用
    • 2. 原理
    • 3. 谷歌 kaptcha 圖檔驗證碼的使用
    • 4. 使用注意事項

1. 驗證碼

1. 作用

表單重複送出有三種常見的情況:

  1. 送出完表單。伺服器使用請求轉來進行頁面跳轉。這個時候,使用者按下功能鍵 F5,就會發起最後一次的請求。 造成表單重複送出問題。

    解決方法:使用重定向來進行跳轉

  2. 使用者正常送出伺服器,但是由于網絡延遲等原因,遲遲未收到伺服器的響應,這個時候,使用者以為送出失敗, 就會着急,然後多點了幾次送出操作,也會造成表單重複送出。
  3. 使用者正常送出伺服器。伺服器也沒有延遲,但是送出完成後,使用者回退浏覽器。重新送出。也會造成表單重複 送出
使用驗證碼,可以避免表單的重複送出;也可以防止機器人通過;

2. 原理

[元件] 1. 驗證碼1. 驗證碼

第一步: 使用者第一次通路表單的時候,就要給表單生成一個随機的驗證碼字元串,浏覽器發起了驗證碼請求,伺服器生成驗證碼字元串并儲存到Session域中,并将驗證碼生成驗證碼圖檔顯示在表單中。

第二步: 使用者輸入驗證碼,點選送出後,發起送出的請求,伺服器接收到請求後,獲得Session中對應key的value,并從session立即移除該驗證碼(使無效invalidate或者移除removeAttribute)。擷取表單項中的資訊,并比較Session中的驗證碼和表單項中的驗證碼是否一緻。

  • 一緻: 允許操作
  • 不一緻: 阻止操作

3. 谷歌 kaptcha 圖檔驗證碼的使用

谷歌驗證碼 kaptcha 使用步驟如下:

  • 導入谷歌驗證碼的 jar 包,可在mvn直接加載依賴 kaptcha-2.3.2.jar
  • web.xml 中去配置用于生成驗證碼的 Servlet 程式
  • 在表單中使用 img 标簽去顯示驗證碼圖檔并使用它
  • 在伺服器端擷取谷歌生成的驗證碼和用戶端發送過來的驗證碼比較使用。
  1. 導入jar包 kaptcha-2.3.2.jar
  2. 在 web.xml 中配置用于生成驗證碼的 Servlet 程式
<servlet>
<servlet-name>KaptchaServlet</servlet-name>
    <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>KaptchaServlet</servlet-name>
    <url-pattern>/kaptcha.jpg</url-pattern>
</servlet-mapping>
           
  1. 表單中使用 img 标簽去顯示驗證碼圖檔并使用它
<label>驗證碼:</label>
<form action="http://localhost:8080/tmp/registServlet" method="get">
	 使用者名:<input type="text" name="username" > <br>
	 驗證碼:<input type="text" style="width: 60px;" name="code">
	 <img src="http://localhost:8080/tmp/kaptcha.jpg" alt="" style="width: 100px; height: 28px;"> <br>
	 <input type="submit" value="登入">
</form>
           
  1. 伺服器端擷取谷歌生成的驗證碼和用戶端發送過來的驗證碼比較
public class RegistServlet extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 擷取Session中的驗證碼
        String token = (String) req.getSession().getAttribute(KAPTCHA_SESSION_KEY);
        // 删除 Session中的驗證碼
        req.getSession().removeAttribute(KAPTCHA_SESSION_KEY);


        String code = req.getParameter("code");
        // 擷取使用者名
        String username = req.getParameter("username");

        if (token != null && token.equalsIgnoreCase(code)) {
            System.out.println("儲存到資料庫:" + username);
            resp.sendRedirect(req.getContextPath() + "/ok.jsp");
        } else {
            System.out.println("請不要重複送出表單");
        }
    }

}
           

4. 使用注意事項

  • 部分浏覽器點選切換驗證碼可能會出現緩存問題,導緻無法點選。

解決方式:

// 給驗證碼的圖檔,綁定單擊事件
$("#code_img").click(function () {
	// 在事件響應的function函數中有一個this對象。這個this對象,是目前正在響應事件的dom對象
	// src屬性表示驗證碼img标簽的 圖檔路徑。它可讀,可寫
	// alert(this.src);
	this.src = "${basePath}kaptcha.jpg?d=" + new Date();
});