Ví dụ minh hoạ công nghệ AJA

Một phần của tài liệu Công nghệ AJAX (Trang 60 - 66)

Chương 3: AJAX – TƯƠNG LAI CỦA ỨNG DỤNG WEB

3.3Ví dụ minh hoạ công nghệ AJA

Trong ví dụ sau, em sẽ tạo một mẫu đơn đăng ký nho nhỏ, yêu cầu người dùng chọn một tên đăng nhập và cung cấp một địa chỉ email không được trùng lặp với bất kỳ ai trong cơ sở dữ liệu đã có. Bằng cách sử dụng Ajax, có thể kiểm tra so sánh với danh sách tên trong cơ sở dữ liệu ngay sau khi người dùng vừa mới nhập tên xong và báo lỗi ngay nếu nó bị trùng (không cần đợi người dùng phải gửi mẫu đơn đi). Điều tương tự xảy ra đối với địa chỉ email, chỉ thêm một cái là kiểm tra luôn định dạng của nó có phải là một địa chỉ email hay không trước khi áp dụng.

Sau khi chọn tên và email xong (tất nhiên là sau khi đã kiểm tra là chúng hợp lệ), người dùng có thể nhấn nút tạo tài khoản - và lần này cũng sử dụng luôn Ajax để thực hiện việc này (minh họa khả năng thay đổi trực tiếp vào cơ sở dữ liệu). Để ý là bạn hoàn toàn không phải rời khỏi trang đăng ký trong bất kỳ giai đoạn nào. Tất cả xảy ra liền mạch và nhanh chóng.

Mặc dù đây là một ví dụ minh họa công nghệ Ajax, em cũng muốn minh họa tầm quan trọng của cách thức tương tác với người dùng. Để ý khi người sử dụng đưa chuột vào một ô nào đó (ô đó sẽ sáng lên cho biết những gì người sử dụng gõ sẽ là vào ô đó), khi có thông báo lỗi (ô bị lỗi sẽ chuyển sang màu đỏ và người sử dụng tự động được chuyển ngược về ô đó để sửa) hay khi dữ liệu của người sử dụng là hợp lệ (ô chuyển sang màu xanh da trời).

Thêm một bước nữa, em đã thiết kế để một khi dữ liệu còn chưa hoàn tất (chưa có đủ tên và email, hoặc tên hay email bị trùng) thì người sử dụng sẽ không thể gửi đơn đi được (nút Submit bị vô hiệu hóa). Chỉ là những ứng dụng rất nhỏ và chi tiết nhưng nó giúp cho ứng dụng của người sử dụng dễ sử dụng hơn rất nhiều.

Ví dụ này được viết sử dụng PHP và cơ sở dữ liệu MySQL. Bài viết phân tích về kỹ thuật Ajax (Asynchronous JavaScript + XML).

Tổng quan

Ví dụ bao gồm 4 file: index.php (giao diện chính), process.php (nơi xử lý các yêu cầu và trả kết quả về dưới dạng XML), scripts.js (chứa các mã javascript), styles.css (định nghĩa giao diện)

Trước khi tìm hiểu sâu vào mã nguồn, trước hết hãy có cái nhìn tổng quan về những gì chúng ta muốn: Chúng ta muốn có một cách nào đó có thể gửi dữ liệu về trang chủ yêu cầu kiểm tra thông tin hoặc thực hiện một tác vụ nào đó và nhận kết quả về mà không cần phải rời trang hiện tại.

Cách chúng ta sẽ thực hiện là sử dụng javascript như một cơ chế nền phía sau giao diện thực hiện việc gửi và nhận kết quả. Hãy cứ tưởng tượng bạn là người phục vụ ở một nhà hàng. Bạn lấy thông tin yêu cầu từ khách hàng và sau đó gửi cho một người chạy bàn (javascript) chuyển các yêu cầu này xuống bếp (máy chủ). Sau khi nhà bếp chuẩn bị xong món ăn, người chạy bàn sẽ chuyển món ăn lên cho bạn để bạn phục vụ khách. Như vậy, bạn sẽ không cần phải rời khỏi khu phục vụ.

Hãy bắt đầu tìm hiểu nhà bếp trước.

process.php - "Nhà bếp"

Bên trong file process.php chỉ đơn thuần chứa các phương thức (hàm) thực hiện các tác vụ kiểm tra, truy vấn cơ sở dữ liệu và trả kết quả về dưới dạng XML. Nội dung các hàm trong ví dụ này hoàn toàn không phức tạp (chỉ là vài câu truy vấn cơ sở dữ liệu), nhưng chú ý là bạn sẽ trả về kết quả dưới dạng XML chứ không phải trang web bình thường.

Cấu trúc của kết quả XML trả về sẽ như sau:

<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?> <response>

<method> method_name </method> <result> result_value </result> </response>

Phương thức generateXMLResult($method_name,$value) sẽ thực hiện việc in kết quả ra dưới dạng XML như trên. Chú ý nữa là ngay dòng đầu tiên của file process.php, bạn cần chỉ rõ phần header.

scripts.js - người bưng đồ và gửi yêu cầu

Đây là phần quan trọng nhất trong kỹ thuật Ajax: sử dụng javascript thông qua đối tượng XMLHttpRequest để gửi các yêu cầu về máy chủ trong chế độ nền.

Trước hết là việc tạo ra đối tượng XMLHttpRequest. Một điểm phức tạp là trình duyệt IE và Mozilla hỗ trợ XMLHttpRequest theo hai phương thức hoàn toàn khác nhau (IE sử dụng ActiveX, còn Mozilla thì hỗ trợ sẵn ngay bên trong trình duyệt) nên để đảm bảo tính tương thích, bạn sẽ cần phải kiểm tra xem người dùng sử dụng trình duyệt nào rồi khởi tạo đối tượng XMLHttpRequest theo cách thức mà trình duyệt đó hỗ trợ.

var req;

function loadXMLDoc(url) {

// branch for native XMLHttpRequest object if (window.XMLHttpRequest) {

req = new XMLHttpRequest();

req.onreadystatechange = processReqChange; req.open("GET", url, true);

req.send(null);

// branch for IE/Windows ActiveX version } else if (window.ActiveXObject) {

req = new ActiveXObject("Microsoft.XMLHTTP"); if (req) {

req.onreadystatechange = processReqChange; req.open("GET", url, true);

} } }

Như vậy, mỗi khi bạn muốn gửi một yêu cầu nào đó lên máy chủ, bạn chỉ cần chuẩn bị địa chỉ bạn muốn gửi yêu cầu đến cùng với các thông tin và sau đó gọi phương thức loadXMLDoc(url). Để ý dòng lệnh:

req.onreadystatechange = processReqChange; (adsbygoogle = window.adsbygoogle || []).push({});

Ý nghĩa của dòng lệnh này là thông báo cho javascript biết một khi đã nhận được bất kỳ phản hồi nào từ máy chủ về yêu cầu này thì sẽ gọi hàm processReqChange. Cần biết là quá trình gửi yêu cầu và nhận yêu cầu được chia làm nhiều giai đoạn (state), từ 0 (mới bắt đầu gửi) cho đến 4 (hoàn tất việc nhận kết quả). Bất kể ở giai đoạn nào, cứ mỗi khi có sự thay đổi là hàm processReqChange sẽ được gọi để kiểm tra những gì nhận được.

Vậy processReqChange sẽ thực hiện các kiểm tra gì?

function processReqChange() { if (req.readyState == 4) { if (req.status == 200) { response=req.responseXML.documentElement; A_Method=response.getElementsByTagName('method')[0].firstChild.data; A_Result=response.getElementsByTagName('result')[0].firstChild.data; if (A_Method!='addNew') { eval(A_Method + '(\'\', A_Result)'); } else { eval(A_Method + '(\'\',\'\', A_Result)');

} } else { alert("ProblemretrievingtheXMLdata:\n"+req.statusText); } } }

Đầu tiên, phương thức kiểm tra xem liệu đã nhận được thông tin cuối cùng từ máy chủ chưa (readyState == 4). Nhưng không chỉ đơn giản vậy, kế tiếp, kiểm tra xem máy chủ gửi về thông báo gì. Nếu không có vấn đề gì thì máy chủ sẽ trả về dữ liệu kết quả dưới dạng XML như chúng ta thiết kế trong process.php - tuy nhiên còn rất nhiều các khả năng khác như quá thời hạn (time-out), file không tìm thấy (lỗi 404-file not found),... Vậy nên chúng ta cần kiểm tra trước và chỉ tiếp tục nếu nhận được đúng dữ liệu chúng ta muốn (status=200).

Một khi nhận được dữ liệu ở dạng XML (đối tượng XML được khởi tạo bằng cách sử dụng thuộc tính responseXML có sẵn của đối tượng XMLHttpRequest), chúng ta cần phân tích nội dung của file XML đó để lấy thông tin kết quả xử lý. Ở đây, ví dụ này sử dụng DOM (Document Object Model) để phân tích.

Chúng ta sẽ phân tích từ nội dung XML chuẩn bị bởi process.php để lấy: 1) tên của phương thức gửi yêu cầu đến máy chủ trước đó, và 2) kết quả xử lý yêu cầu đó. Chúng ta cần biết tên phương thức gọi yêu cầu để có thể gọi lại và yêu cầu thực hiện các thay đổi trên giao diện (cũng giống như người phục vụ sẽ cần phải biết được món nào của bàn nào sau khi nhận món ăn từ người bưng đồ).

Cuối cùng, hãy thử phân tích xem chúng ta sẽ thực hiện việc gửi yêu cầu, nhận yêu cầu và thực hiện các thay đổi như thế nào qua một ví dụ.

Hãy lấy ví dụ đơn giản nhất là kiểm tra thử tên người dùng đã có trong cơ sở dữ liệu chưa (xem thử ví dụ trước). Việc kiểm tra sẽ được thực hiện ngay mỗi khi người dùng nhập xong tên và chuyển sang ô khác (nhấn chuột ra ngoài hay nhấn "tab" trên bàn phím) bằng cách sử dụng phương thức "onblur":

<input name="username" type="text" onblur="checkName(this.value,'')" />

Như ở trên, mỗi khi người dùng chuyển sang ô khác, phương thức checkName sẽ được gọi kèm theo nội dung mà người dùng mới nhập vào để gửi đi kiểm tra:

Function checkName(input,response) { if(response!='') { message=document.getElementById('nameCheckFailed'); if(response==0){ document.getElementById("name").focus(); message.className='error'; document.getElementById("name").className="textForm_Error"; name_OK=false; } else { message.className='hidden'; document.getElementById("name").className="textForm_Accept"; name_OK=true; } checkReady(); } else { if(input!='') { url='http://localhost/ajaxexample/process.php?task=1&q='+input; loadXMLDoc(url); }

else { name_OK=false; } } }

Phương thức checkName sẽ thực hiện 2 nhiệm vụ: nếu như response!="", tức là nhận được phản hồi từ máy chủ, thì nó sẽ thực hiện các thay đổi trên giao diện. Ngược lại có nghĩa là chưa có yêu cầu hoặc phàn hổi nào cả thì nó sẽ thực hiện việc gửi yêu cầu (để ý cách chuẩn bị nội dung gửi lên qua phương thức GET trong url). Đây cũng chính là lí do tại sao chúng ta cần phải biết tên phương thức gửi yêu cầu trong hàm processReqChange để có thể yêu cầu lại chính phương thức đó thực hiện các thay đổi trên giao diện mà nó muốn.

Trong file scripts.js còn rất nhiều các phương thức tương tự (như checkEmail, addNew,...) có cách họat động hoàn toàn giống phương thức trên.

3.4 Kết luận

Khi các kho dữ liệu trên mạng ngày càng được cập nhật và mở rộng với đầy đủ các dạng lưu trữ như văn bản, âm thanh, hình ảnh… thời gian tìm kiếm và xử lý thông tin giữa một trang web khi tương tác với server cần được giảm thiểu để mang lại hiệu quả cao nhất.

AJAX thực sự là một mô hình lập trình web mới cho phép xử lý các yêu cầu của người sử dụng đối với các ứng dụng cài đặt trên web server có thể chạy nhanh chóng như được cài đặt ngay trên một máy tính để bàn.

Chỉ mới xuất hiện trong một thời gian ngắn nhưng công nghệ Ajax đã tỏ ra rất hứa hẹn, thậm chí đến nay người ta vẫn chưa khám phá ra hết những gì công nghệ này có thể làm được.

Một phần của tài liệu Công nghệ AJAX (Trang 60 - 66)