AJAX - tương lai cho ứng dụng Web (1)  
 

(Post 15/11/2005)

Trong khoảng 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 quan tâ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.

Tôi là một trong số những người luôn ngạc nhiên trước tốc độ xử lý của Gmail (http://gmail.google.com). Cảm giác của tôi khi dùng Gmail rất giống như một ứng dụng desktop: khi nhấp vào một liên kết, thay vì phải đợi cả trang Web tải lại, mọi thứ hiện ra gần như tức thì. Với sự ra đời của Gmail và những trang Web khác như Google Maps (http://map.google.com), Google Suggest (http://www.google.com/webhp?complete=1&hl=en) của Google, tất cả cộng đồng sử dụng Internet trên thế giới đều nhận ra rằng một ứng dụng trên Web cũng có thể tốt như một ứng dụng cài đặt trên máy của họ.

Gần đây tôi có nghe giải thích trên một tờ báo tin học rằng sở dĩ Gmail có thể nhanh như vậy là dùng ActiveX. Nhưng nếu bạn thử Gmail trên Firefox hay Opera, tốc độ của ứng dụng cũng không hề thay đổi mà hai trình duyệt này không hề có khái niệm về ActiveX - một công nghệ độc quyền của Microsoft.

Vậy bí quyết nào đứng đằng sau các trang web này của Google? Đó là một “công nghệ” có cái tên gợi tới một CLB bóng đá của Hà Lan: AJAX.

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<brands.length; 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 = "<table border=\"0\" align=\"center\"
cellpadding=\"1\" cellspacing=\"0\" width=\"100%\" class=DataGrid1>";
html += "<tr class=DataGrid2Header>";
html += "<th>Model</th>";
html += "<th>Trọng Lượng</th>";
html += "<th>Kích Thước</th>";
html += "<th>Bộ Nhớ</th>";
html += "<th>Màn Hình</th>";
html += "<th>Giá (triệu đ)</th>";
if(displayPicture.equalsIgnoreCase("yes"))
html += "<th>Hình</th>";
html += "</tr>";
int row =0;
for (Iterator it = mobiles.iterator(); it.hasNext();) {
HashMap hm = (HashMap)it.next();
if(row%2 == 0)
html += "<tr class=DataGrid1Style align=center>";
else
html += "<tr class=DataGrid1StyleAlternate align=center>";
html += "<td valign=middle>" + (String)hm.get("model") + "</td>";
html += "<td valign=middle>" + (String)hm.get("weight") + "</td>";
html += "<td valign=middle>" + (String)hm.get("size") + "</td>";
html += "<td valign=middle>" + (String)hm.get("RAM") + "</td>";
html += "<td valign=middle>" + (String)hm.get("graphic")+ "</td>";
html += "<td valign=middle>" + (String)hm.get("price")+ "</td>";
if(displayPicture.equalsIgnoreCase("yes"))
html += "<td valign=middle><img src=\""
+ myWebPath + "images/mobile/" + (String)hm.get("picture")+ "\"></td>";
html += "</tr>";
row++;
}
html += "</table>";
// Write the HTML to response
out.write(html);

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

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.

(theo JavaVietNam Organization)


 
 

 
     
 
Công nghệ khác:


Ajax: A New Approach to Web Applications - by Jesse James GarrettThe Evolution of Cellular Data: On the Road to 3G
Paperless PaperLưu cất và phục hồi SQL Server
RSS: chìa khoá vàng cho việc chia sẻ thông tinMarkup Languages
  Xem tiếp    
 
Lịch khai giảng của hệ thống
 
Ngày
Giờ
T.Tâm
TP Hồ Chí Minh
Hà Nội
 
   
New ADSE - Nhấn vào để xem chi tiết
Mừng Sinh Nhật Lần Thứ 20 FPT-APTECH
Nhấn vào để xem chi tiết
Bảng Vàng Thành Tích Sinh Viên FPT APTECH - Nhấn vào để xem chi tiết
Cập nhật công nghệ miễn phí cho tất cả cựu sinh viên APTECH toàn quốc
Tiết Thực Vì Cộng Đồng
Hội Thảo CNTT
Những khoảnh khắc không phai của Thầy Trò FPT-APTECH Ngày 20-11