Viết thư viện captcha và kiểm tra mã captcha bằng ajax - Học Ajax - PHP Ajax - jQuery Ajax
Nếu như bạn hay lướt web thì bạn sẽ thấy có những website khi bạn đăng ký thành viên hoặc là gửi thông tin liên hệ thì họ sẽ có những mã code cho bạn nhập vào, những đoạn mã này có mục đích là chống spam vì nó được sinh ra ngẫu nhiên. Những đoạn mã như vậy người ta gọi là mã captcha, hay còn gọi là ...
Nếu như bạn hay lướt web thì bạn sẽ thấy có những website khi bạn đăng ký thành viên hoặc là gửi thông tin liên hệ thì họ sẽ có những mã code cho bạn nhập vào, những đoạn mã này có mục đích là chống spam vì nó được sinh ra ngẫu nhiên. Những đoạn mã như vậy người ta gọi là mã captcha, hay còn gọi là mã chống spam.
Vậy trong bài này tôi sẽ hướng dẫn các bạn tạo một thư viện captcha bằng php cho riêng mình, đồng thời học cách sử dụng thư viện captcha, cách hiển thị captcha ra form và sử dụng ajax để validate captcha. Ta bắt đầu nhé.
1. Tạo thư viện captcha bằng php
Công việc đầu tiên là bạn phải tạo một thư viện captcha, đây là thư viện mà tôi viết sẵn nên các bạn xem trực tiếp trên nó nhé, tôi chỉ hướng dẫn cách sư dụng.
Bạn tạo file captcha.php với nội dung sau:
class Captcha { var $img_width = 120; var $img_height = 30; var $font_path = './fonts'; // đường dẫn đên thư mục file text var $fonts = array(); var $font_size = 15; var $char_set = "ABCDEFGHJKLMNPQRSTUVWXYZ2345689"; var $char_length = 5; var $char_color = "#880000,#008800,#000088,#888800,#880088,#008888,#000000"; var $char_colors = array(); var $line_count = 10; var $line_color = "#DD6666,#66DD66,#6666DD,#DDDD66,#DD66DD,#66DDDD,#666666"; var $line_colors = array(); var $bg_color = '#FFFFFF'; // Khởi tạo cấu hình, hàm này sẽ trả về mã code và hiển thị hình function get_and_show_image( $override = array() ) { // Override lại thong số config if( is_array( $override) ) { foreach ( $override as $key => $value) { if( isset( $this->$key )) $this->$key = $value; } } // Tạo danh sách colors thành một mảng $this->line_colors = preg_split("/,s*?/", $this->line_color ); $this->char_colors = preg_split("/,s*?/", $this->char_color ); // Lấy danh sách fonts trong folder được định nghĩa trong biến font_path $this->fonts = $this->collect_files( $this->font_path, "ttf"); // Khởi tạo hình ảnh $img = imagecreatetruecolor( $this->img_width, $this->img_height); imagefilledrectangle($img, 0, 0, $this->img_width - 1, $this->img_height - 1, $this->gd_color( $this->bg_color )); // Vẽ hình lung tung cho đời nó tươi mát for ($i = 0; $i < $this->line_count; $i++){ imageline($img, rand(0, $this->img_width - 1), rand(0, $this->img_height - 1), rand(0, $this->img_width - 1), rand(0, $this->img_height - 1), $this->gd_color($this->line_colors[rand(0, count($this->line_colors) - 1)]) ); } // Vẽ code lên hình $code = ""; $y = ($this->img_height / 2) + ( $this->font_size / 2); for ($i = 0; $i < $this->char_length ; $i++) { $color = $this->gd_color( $this->char_colors[rand(0, count($this->char_colors) - 1)] ); $angle = rand(-30, 30); $char = substr( $this->char_set, rand(0, strlen($this->char_set) - 1), 1); $sel_font = $this->fonts[rand(0, count($this->fonts) - 1)]; $font = $this->font_path . "/" . $sel_font; $x = (intval(( $this->img_width / $this->char_length) * $i) + ( $this->font_size / 2)); $code .= $char; imagettftext($img, $this->font_size, $angle, $x, $y, $color, $font, $char); } // Hiển thị ảnh header('content-type: image/jpg'); ImageJPeg( $img); return $code; } // Chuyển color function gd_color($html_color) { return preg_match('/^#?([dA-F]{6})$/i', $html_color, $rgb) ? hexdec($rgb[1]) : false; } // Lấy danh sách file theo phần mở rộng (ext) function collect_files($dir, $ext) { if (false !== ($dir = opendir($dir))) { $files = array(); while (false !== ($file = readdir($dir))) if (preg_match("/\.$ext$/i", $file)) $files[] = $file; return $files; } return false; } }
Trong thư viện captcha này bạn cần cấu hình những thông số như sau:
- Thuộc tính
$font_path
là nơi chứa những file font chữ của captcha - Thuộc tính
$img_width
là chiều dài của hình ảnh trả về - Thuộc tính
$img_height
là chiều cao của hình ảnh trả về - Thuộc tính
$char_length
là chiều dài của mã code captcha - Thuộc tính
$bg_color
là mã màu của background, mặc định là màu trắng (FFFFFF), - Thuộc tính
$font_size
là kích thước của chữ in trên hình captcha
Cấu trúc folder sẽ có dạng như sau:
Ở đây bạn chỉ cần chú ý đến folder fonts, đây là folder chứa những file font chữ của captcha,
2. Tạo file hiển thị hình ảnh captcha bằng php
Trong bước này ta sẽ hiển thị hình ảnh captcha thông qua một file PHP, ở file này sẽ import file captcha.php, khởi tạo đối tượng captcha và lưu vào SESSION nhằm mục đích dùng để validate khi người dùng submit form.
Bạn tạo file image.php với nội dung như sau:
<?php session_start(); require("captcha.php"); $captcha = new Captcha(); $code = $captcha->get_and_show_image(); // Lưu code session $_SESSION['captcha_code'] = $code; ?>
Bước này rất đơn giản, quan trọng nhất là ở đoạn code lưu SESSION, nếu ta không lưu thì ta sẽ không biết được mã code hiện tại là bao nhiêu để validate.
3. Tạo form liên hệ hiển thị captcha
Bây giờ tôi sẽ tạo form liên hệ, và để đơn giản tôi chỉ hiển thị một form đơn giản với một nội dung duy nhất đó là content. Bạn tạo file index.php với nội dung như sau:
<!DOCTYPE html> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script language="javascript" src="http://code.jquery.com/jquery-2.0.0.min.js"></script> </head> <body style="width: 500px; margin: 0px auto;"> <form id="mainform" method="post" action=""> <table border="1" cellspacing="0" cellpadding="5"> <tr> <td>Nội dung</td> <td><textarea id="content" cols="40" rows="5"></textarea></td> </tr> <tr> <td>Captcha</td> <td> <img src="image.php" id="img-captcha"/> <input type="button" value="Reload" onclick="$('#img-captcha').attr('src', 'image.php?rand=' + Math.random())" /> <br/> <input type="text" id="captcha" value="" /> </td> </tr> <tr> <td>Captcha</td> <td> <input id="submit" type="submit" value="Lưu" /> </td> </tr> </table> </form> <script language="javascript"> $(document).ready(function(){ $('#submit').click(function() { // Lấy dự liệu var data = { content : $('#content').val(), captcha : $('#captcha').val() }; // Validate if ($.trim(data.content) == ''){ alert('Bạn chưa nhập nội dung'); } else if ($.trim(data.captcha) == ''){ alert('Bạn chưa nhập captcha'); } else{ $.ajax({ type : 'POST', dataType : 'json', url : 'ajax_validate.php', data : data, success : function (result){ if (!result.hasOwnProperty('error')){ alert('Kết quả trả về không phù hợp'); } else if (result['error'] == 'success'){ $('#mainform').submit(); alert('Kiểm tra thành công'); } else{ if (result['content'] != ''){ alert(result['content']); } if (result['captcha'] != ''){ alert(result['captcha']); } } }, error : function (){ alert('Có lỗi xảy ra trong quá trình xử lý'); } }); } return false; }); }); </script> </body> </html>
Trong đó đoạn code dưới đây dùng để hiển thị captcha nên trong src của thẻ image tôi có trỏ đên file captcha.php. Và mỗi lần click vào button reload tôi sẽ thay thông số random trên SRC của thẻ captcha với mục đích load lại hình ảnh, vì nếu không làm vậy thì bộ nhớ của trình duyệt sẽ ko gọi đến server để đổi code.
<tr> <td>Captcha</td> <td> <img src="image.php" id="img-captcha"/> <input type="button" value="Reload" onclick="$('#img-captcha').attr('src', 'image.php?rand=' + Math.random())" /> <br/> <input type="text" id="captcha" value="" /> </td> </tr>
Đoạn code dưới đây dùng để gửi ajax kiểm tra thông tin người dùng nhập vào:
$(document).ready(function(){ $('#submit').click(function() { // Lấy dự liệu var data = { content : $('#content').val(), captcha : $('#captcha').val() }; // Validate if ($.trim(data.content) == ''){ alert('Bạn chưa nhập nội dung'); } else if ($.trim(data.captcha) == ''){ alert('Bạn chưa nhập captcha'); } else{ $.ajax({ type : 'POST', dataType : 'json', url : 'ajax_validate.php', data : data, success : function (result){ if (!result.hasOwnProperty('error')){ alert('Kết quả trả về không phù hợp'); } else if (result['error'] == 'success'){ $('#mainform').submit(); alert('Kiểm tra thành công'); } else{ if (result['content'] != ''){ alert(result['content']); } if (result['captcha'] != ''){ alert(result['captcha']); } } }, error : function (){ alert('Có lỗi xảy ra trong quá trình xử lý'); } }); } return false; }); });
4. Tạo trang nhận request ajax kiểm tra mã captcha bằng php
Bước này ta sẽ tạo một file ajax_validate.php
, nội dung của file này sẽ lấy dữ liệu từ đoạn code gửi ajax bên file index.php
session_start(); // Lấy thông tin $content = isset($_POST['content']) ? $_POST['content'] : false; $captcha = isset($_POST['captcha']) ? $_POST['captcha'] : false; // Biến lưu kết quả trả về $error = array( 'error' => 'success', 'content' => '', 'captcha' => '' ); // Kiểm tra content if (!$content){ $error['content'] = 'Bạn chưa nhập nội dung'; $error['error'] = 'error'; } // Kiểm tra captcha if (!$captcha){ $error['captcha'] = 'Bạn chưa nhập captcha'; $error['error'] = 'error'; } else if (!isset($_SESSION['captcha_code']) || $_SESSION['captcha_code'] != trim($captcha)) { $error['captcha'] = 'Captcha bạn nhập không đúng'; $error['error'] = 'error'; } // Trả kết quả cho client die (json_encode($error));
Trong file này bạn chỉ cần chú ý đến những đoạn code comment mà tôi dùng để kiểm tra mã captcha. Vì ở file image.php tôi lưu code vào SESSION nên ở đây tôi sẽ kiểm tra và gọi session để so sánh thông số rồi trả về kết quả
Chạy lên ta ta sẽ có như hình ảnh dưới đây:
5. Lời kết
Bài này mình chỉ muốn giới thiệu thư viện captcha và cách sử dụng nó như hiển thị captcha, reload capcha,... đồng thời hướng dẫn các bạn cách sử dụng Ajax để validate form. Vì bài khá đơn giản nên mình không sử dụng database để lưu trữ.