AJAX-Tương lai cho ứng dụng Web (phần 1)

Trong khỏang thời gian gần đây , các nhà cung cấp dịch vụ web trên thế giới đang chạy đua nâng cấp dung lượng hộp mail nhằm chiếm lấy một số lượng thị phần đáng kể , người sử dụng không còn quantâm nhiều đền dung lượng hộp mail như trước đây, thay vào đó họ bắt đầu quan tâm nhiều đến tốc độ duyệt mail .

1. Vậy AJAX là gì?

    Nó mới chỉ xuất hiên lần đầu vào tháng 2 năm nay (2005), khi Jesse James Garrett của công ty AdapativePath định nghĩa và tóm gọn lại từ cụm từ “Asynchronous JavaScript+CSS+DOM+XMLHttpRequest” . Ngay sau đó cụm từ AJAX được phổ biến cực
kỳ nhanh chóng trong cộng đồng phát triển Web và đến giờ nó là một trong những từ khóa được tìm kiếm nhiều nhất trên Internet.

    Và đây là định nghĩa của Garrett về AJAX:

AJAX không phải là một công nghệ. Nó là tập hợp của nhiều công nghệ với thế mạnh của riêng mình để tạo thành một sức mạnh mới. AJAX bao gồm:

     * Thể hiện web theo tiêu chuẩn XHTML và CSS;
     * Nâng cao tính năng động và phản hồi bằng DOM (Document Object Model );
     * Trao đổi và xử lý dữ liệu bằng XML và XSLT;
     * Truy cập dữ liệu theo kiểu bất đồng bộ (asynchronous) bằng XMLHttpRequest;
     * Và tất cả các kỹ thuật trên được liên kết lại với nhau bằng JavaScript .

    Đến đây có lẽ bạn đang tự nhủ: có vẻ đây là một công nghệ rất phức tạp. Không hẳn vậy! Điểm mấu chốt của Ajax nằm ở XMLHttpRequest. Đây là một kỹ thuật do Microsoft khởi xướng và tích hợp lần đầu tiên vào IE5 dưới dạng một ActiveX . Mozilla tích hợp công nghệ này vào Mozilla 1.0/Netscape 6 sau đó. Và dĩ nhiên tất cả các version của
Firefox đều hỗ trợ XMLHttpRequest , hiện nay đã có trong trình duyệt Safari 1.2 (Apple) và Opera 8 trở lên .Chúng ta sẽ trở về với XMLHttpRequest và cách sử dụng nó trên các trình duyệt khác nhau ở phần sau.

  Bây giờ hãy thử một ứng dụng đơn giản sử dụng AJAX: Mobile Phone Catalog tại liên kết này:

http://www.myjavaserver.com/~quangvhg/MobileCatalog.jsp

Đây là một danh sách các model điện thoại di động, tính năng của chúng xếp theo tên hãng chế tạo.

    Khi bạn đánh dấu hộp kiểm chọn các nhãn hiệu, lập tức danh sách điện thoại của các các hãng xuất hiện ngay ở bảng phía dưới mà không cần tải lại cả trang Web.

    So với cách thông thường, khi người dùng có một cần thay đổi dữ liệu trên trang Web, yêu cầu thay đổi được gửi về server dưới dạng HTTP request (hay còn gọi postback), server sẽ xử lý yêu cầu này và gửi trả lại trang HTML khác thay thế trang cũ. Qui trình này được mô tả là nhấp-chờ và tải lại (click-wait-and-refresh): ví dụ người dùng sau khi nhấn một nút “Submit” trên trang web phải chờ cho đến khi server xử lý xong mới có thể tiếp tục công việc. Ngược lại, trong ví dụ trên bạn có thể nhấn liên tục vài hộp kiểm để chọn/bỏ chọn các nhãn hiệu mà không cần chờ đợi.

Đây là mô hình “cổ điển” của một ứng dụng Web:

Và đây là mô hình sử dụng AJAX:

 

    Rõ ràng điểm khác biệt là thay vì phải tải cả trang web thì với AJAX bạn chỉ cần tải về phần của trang Web mà bạn muốn thay đổi. Điều này giúp cho ứng dụng web của bạn phản hồi nhanh hơn, thông minh hơn. Ngoài ra, điểm đặc biệt quan trọng trong công nghệ AJAX nằm ở chữ A (Asynchronous) – bất đồng bộ – tức là bạn cứ gửi yêu cầu của mình tới server và quay lại với công việc của mình mà không cần chờ trả lời. Khi nào server xử lý xong yêu cầu của bạn, nó sẽ báo hiệu và bạn có thể “bắt lấy” để thể hiện những thay đổi cần thiết. Vậy tất cả cơ chế này hoạt động thực sự thế nào? Chúng ta sẽ xem có gì trong source code của ví dụ Mobile Phone Catalog.

2. Digging into source code

    Thông thường một ứng dụng AJAX cần có hai thành phần (hay nhiều hơn): tạm gọi là front-end và back-end.

 

    Front-end dùng để thể gửi các XMLHttpRequest và thể hiện các thay đổi, còn back-end để xử lý các request và trả lại kết quả thay đổi cho front-end.

    Trong Mobile Phone Catalog, trang front-end (MobileCatalog.jsp ) rất đơn giản và không có gì thú vị ngoại trừ đoạn mã JavaScript.

    Mỗi khi người dùng chọn/bỏ chọn một hộp kiểm sẽ kích hoạt hàm displayItems():

function displayItems() {

var params = “brands=”;

// check to see which checkboxes are checked and append them to the string.
if (document.getElementById('checkBox1').checked == true) {
params += “,Nokia”
}
// more here

retrieveURL(“MobileCatalogRender.jsp?” + params);

return true;
}

    Hàm này sẽ xem có những nhãn hiệu nào được chọn và tạo nên một chuỗi (String) request. (ví dụ nếu “Nokia” và “Samsung” được chọn thì chuồi này sẽ có dạng “MobileCatalogRender.jsp?brands=,Nokia,Samsung ”) và gửi chuỗi này tới hàm retrieveURL() . Đây là hàm quan trọng nhất nên ta sẽ xem xét kỹ từng dòng và ý nghĩa của các dòng lệnh này:


1. function retrieveURL(url) {
2. if (window.XMLHttpRequest) { // Non-IE browsers
3. req = new XMLHttpRequest();
4. req.onreadystatechange = processStateChange;
5. try {
6. req.open(“GET”, url, true);
7. } catch (e) {
8. alert(e);
9. }
10. req.send(null);
11. } else if (window.ActiveXObject) { // IE
12. req = new ActiveXObject(“Microsoft.XMLHTTP”);
13. if (req) {
14. req.onreadystatechange = processStateChange;
15. req.open(“GET”, url, true);
16. req.send();
17. }
18. }
19. }

– Dòng 2/dòng 11: Kiểm tra xem trình duyệt có hỗ trợ XMLHttpRequest hay không. Trong đó dòng 11 dùng cho trình duyệt của Microsoft
– Internet Explorer (như các bạn thấy chúng ta phải tạo một ActiveX) còn dòng 2 dùng cho các trình duyệt khác (Mozilla, Safari, Opera).
– Dòng 3/dòng 12: khời tạo đối tượng XMLHttpRequest.
– Dòng 4/dòng 14: Gán event handler khi có phản hồi. Đây là dòng lệnh có ý nghĩa đặc biệt, nó cho phép chúng ta nhận phản hồi của back-end
và cập nhật các thay đổi trên front-end.
– Dòng 6/dòng 15+16: Gửi request từ front-end tới back-end dưới dạng một HTTP request. Ở đây chuỗi request là “MobileCatalogRender.jsp?brands=,Nokia,Samsung ”.

    Sau khi gửi request đi, nếu có bất kỳ phản hồi gì từ back-end hàm processStateChange() sẽ được kích hoạt. Trong trường hợp lý tưởng back-end sẽ trả về một bảng danh sách các model điện thoại di động của hai hãng Nokia và Samsung. Hàm processStateChange() sẽ gán đoạn HTML trả về này vào div “theTable”, ngược lại sẽ hiện lên một thông báo lỗi:

function processStateChange() {
if (req.readyState == 4) { // Complete
if (req.status == 200) { // OK response
document.getElementById(“theTable”).innerHTML = req.responseText;
} else {
alert(“Problem: ” + req.statusText);
}
}
}


    Cuối cùng là mã của back-end (MobileCatalogRender.jsp). Đây là một trang Java Server Page có nhiệm vụ xử lý request và trả lại một bảng dữ liệu tương ứng (bạn có hoàn toàn có thể dùng một servlet thay cho trang này). Đây là trích mã nguồn, chắc các bạn có thể dễ dàng hiễu được.

String param1 = (String)request.getParameter(“brands”);
String displayPicture = (String)request.getParameter(“picture”);

if (param1 == null) {
param1 = “”;
}

if (displayPicture == null) {
displayPicture = “no”;
}

String[] brands = param1.split(“,”);
ArrayList mobiles = new ArrayList();
for(int j=0; j if(brands[j].equalsIgnoreCase(“nokia”)){
mobiles.add(nokia1());
mobiles.add(nokia2());
mobiles.add(nokia3());
}

if(brands[j].equalsIgnoreCase(“samsung”)){
mobiles.add(samsung1());
mobiles.add(samsung2());
mobiles.add(samsung3());
}
if(brands[j].equalsIgnoreCase(“motorola”)){
mobiles.add(moto1());
mobiles.add(moto2());
mobiles.add(moto3());
}
}

// And yes, I know creating HTML in an Action is generally very bad form,
// but I wanted to keep this exampel simple.
String html = ”

ModelTrọng LượngKích ThướcBộ NhớMàn HìnhGiá (triệu đ)Hình
” + (String)hm.get(“model”) + “” + (String)hm.get(“weight”) + “” + (String)hm.get(“size”) + “” + (String)hm.get(“RAM”) + “” + (String)hm.get(“graphic”)+ “” + (String)hm.get(“price”)+ “ + myWebPath + “images/mobile/” + (String)hm.get(“picture”)+ “”>

“;

// Write the HTML to response
out.write(html);

3. Một vài ví dụ khác:

+ Danh sách khách hàng có thể “sort” bằng cách nhấp vào thanh tiêu đề:

http://www.myjavaserver.com/~quangvhg/SortableTable.jsp

+ Từ Điển AJAX (cực nhanh):

http://www.myjavaserver.com/~fastdict

+ Cờ Ca-rô (Gomoku) ứng dụng AJAX

http://myjavaserver.com/~quangvhg/GomokuBoard.jsp?lang=vi

Tuy các ví dụ ở đây viết bằng Java, AJAX không bó hẹp ở J2EE mà có thể thực hiện ở các nền tảng khác như .Net hay PHP.

Hy vọng bài viết này sẽ có ích phần nào với các bạn.