Thứ Hai, 29 tháng 10, 2012

Ajax jQuery và những điều cần biết

Điều đầu tiên trước khi bước vào tut, mình nói trước mình sẽ không theo cái cách viết tut truyền thống như Ajax là gì, viết tắt của cái gì, ra đời năm nào... NO! Mình sẽ đi vào thẳng vấn đề, ứng dụng của Ajax là gì và làm thế nào để dùng Ajax với thư viện jQuery.
Trong bài này, chúng ta sẽ tìm hiểu về 4 hàm trong jQuery sử dụng thường xuyên để tương tác với Ajax - đặc biệt là hàm jQuery.ajax():

* jQuery.ajax() [Đây là phương pháp ngắn nhất, thay thế cho tất cả những thứ liên quan đến jQuery Ajax như          

* jQuery.get() + jQuery.post() + jQuery.ajaxStart() + jQuery.ajaxStop()...]
* jQuery.ajaxSetup()//Cài đặt những tham số mặc định cho jQuery.ajax()
* jQuery.getScript()
* jQuery.load() //Hàm này hay lắm á xD
BONUS: Dùng Ajax để tương tác với file XML

Đầu tiên nói về ajax, ajax là gì? Hiểu đơn giản, Ajax là lấy thông tin từ 1 trang khác mà không cần load lại trang hiện tại. Điều này đặc biệt hữu ích khi người dùng không phải load lại những thứ cần thiết. Hình dung như sau:
Khi người dùng nhập vào 1 form đăng ký thành viên chẳng hạn, theo truyền thống, bạn phải submit() form đó, rồi nó kiếm tra là tên đã có người đăng ký hay chưa rồi mới quay lại thông báo rằng tên đã có ng` đăng ký. Khi dùng Ajax, người dùng vừa nhập vào tên, trình duyệt sẽ tự động gửi ngầm dữ liệu đến 1 trang khác [gọi là trang kiểm tra] để kiểm tra, nhiệm vụ của trang kiểm tra là lục cơ sở dữ liệu, trả về true nếu tên đã tồn tại, trả về false nếu tên chưa tồn tại, và như thế là ta có thể biết được tên có tồn tại hay chưa để xử lý mà không cần phải tải lại trang.
Vậy là hiểu đơn giản nhé, Ajax là gửi ngầm thông tin đi, xử lý, nhận kết quả trả về và dùng kết quả trả về để làm gì cũng được, tất nhiên, toàn bộ quá trình không load lại trang.
1) jQuery.ajax() = $.ajax();
Đây là hàm cơ bản và hữu dụng nhất khi dùng ajax.

PHP Code:

$.ajax(
    {
url: "Địa chỉ của trang nhận dữ liệu để xử lý, ví dụ check.php, check.html...",
type: "GET hoặc POST",//Mặc định là GET
dataType: "Mặc định tự nhận dạng, có thể cài đặt xml, json, jsonp, script, html hoặc text",
data: "Dữ liệu gửi đi, ví dụ name=xx3004&password=123456&nickname=timmy",
crossDomain: "Mặc định là false, giải thích sau",
success(data, textStatus, jqXHR)
        {
//Dữ liệu trả về sẽ dc gán trong biến data
        //Dùng dữ liệu trả về làm gì cũng dc
        //Còn hai cái kia thì cũng chả biết làm gì, để cho đẹp vậy
}
error(jqXHR, textStatus, errorThrown)
        {
//jqXHR, textStatus và errorThrown sẽ chưa thông báo về lỗi xảy ra để dễ debug, ví dụ như Timeout, hoặc URL NOT FOUND...
}
    });

Bùm, xong. Đơn giản không, bây giờ quay vào ví dụ chính, thực hành cho dễ hiểu, giả sử bạn có 1 form đăng ký:

PHP Code:

<form action="register.php" method="POST">
<input type="text" id="userID"> <span id="status">Please enter your desire ID</span>
<br>
<input type="submit" value="REGISTER">
</form>

Cái <span></span> là để update thông báo, ví dụ như là "Không được để trống", "Tên đã tồn tại"... chẳng hạn.
OK, bạn muốn rằng mỗi khi người dùng nhập vào id gì đó, thì nó tự động kiểm tra xem id có tồn tại hay chưa, bằng cách gửi thông tin đến trang check.php.

PHP Code:

//check.php
...//Nhận dữ liệu rồi xử lý gì đó, muốn làm gì thì làm
//Trả về true nếu tên đã tồn tại trong Cơ Sở Dữ Liệu
//Trả về false nếu tên ko tồn tại CSDL

Bây giờ gán cho cái <input> chức năng gửi dữ liệu để kiểm tra mỗi khi người dùng bấm 1 phím nào đó:

PHP Code:

$("#userID").keyPress(function()
    {
//Gửi dữ liệu tới check.php, nhận dữ liệu trả về
    //Nếu dữ liệu trả về là true >> Thông báo tên đã tồn tại
    //Nếu dữ liệu trả về là false >> Tên không tồn tại, có thể sử dụng
});

Rồi, bây giờ xem đoạn code jQuery.ajax() cần những gì nha. URL? Ở đây là check.php. Type? GET hoặc POST, tùy vào trang xử lý php. dataType? Để mặc định cho nó tự nhận dạng đỡ mắc công. data? Ở đây data gửi đi là userID=ValueCủaCáiInput, tức là $("#userID").val(). Khi thành công [success()]? Kiểm tra dữ liệu rồi xuất thông báo. Khi gặp lỗi [error()]? Thông báo có lỗi. Có hết thông tin rồi, giờ chỉ cần gán nó vào:

PHP Code:

$("#userID").keyPress(function()
    {
    $.ajax(
        {
url: "check.php",
type: "GET",//Giả sử là GET đi
data: "userID=" + $("#userID").val(),
success(data, textStatus, jqXHR)
            {
            if(data==true)
                {
                $("#status").html("Tên đã tồn tại!");
                }
            else if(data==false)
                {
                $("#status").html("Tên có thể sử dụng");
                }
            }
error(jqXHR, textStatus, errorThrown)
            {
alert("Có lỗi xảy ra!");
            }
        });
    });

Vậy là xong rồi đó. Ajax với jQuery đơn giản phải ko? Tiếp theo chúng ta sẽ nói đến Cross Domain trong Ajax. Mặc định Ajax chỉ cho bạn gửi và nhận dữ liệu từ trang web có cùng domain, bạn không thể dùng Ajax để gửi dữ liệu từ site bạn để đăng nhập vào Yahoo! Mail được,... Tuy nhiên vẫn có thể phá được giới hạn đó = cách cài crossDomain giá trị = true, như đoạn code ở trên:

PHP Code:

$("#userID").keyPress(function()
    {
    $.ajax(
        {
url: "http://www.ddth.com/check.php",//Giả sử file check ko còn cùng domain nữa
crossDomain: true,//Cài giá trị cho crossDomain = true
type: "GET",
data: "userID=" + $("#userID").val(),
success(data, textStatus, jqXHR)
            {
            if(data==true)
                {
                $("#status").html("Tên đã tồn tại!");
                }
            else if(data==false)
                {
                $("#status").html("Tên có thể sử dụng");
                }
            }
error(jqXHR, textStatus, errorThrown)
            {
alert("Có lỗi xảy ra!");
            }
        });
    });

Vì tính bảo mật, phương thức trên sẽ ko hoạt động trên 1 số site, đến lúc đó, cách duy nhất là hack code, [theo mình biết thì là đổi tên tạm thời cái domain đó bằng 1 vài thủ thuật, lợi dụng việc thêm ký tự "#" vào cuối trang web không làm trang web tải lại...]. Vì đây là tut về Ajax, mình sẽ không đi sâu vào vấn đề này.
2)jQuery.ajaxSetup() = $.ajaxSetup();
Giả sử tất cả những gì bạn gửi đi đều có chung 1 vài thuộc tính thì bạn làm thế nào? Giả sử như bạn muốn nếu có lỗi xảy ra thì thông báo lỗi, thế nhưng không lẽ cứ mỗi lần viết 1 hàm Ajax lại phải lập lại cái error() chán ngấy đó? Cách đơn giản là dùng ajaxSetup(), cài mặc định tham số cho Ajax. Cách dùng y chang ở trên thôi, ko có gì cả, ví dụ như:

PHP Code:

$(document).ready(function()
    {
    $.ajaxSetup(
        {
crossDomain: true,
type: "GET",
error(jqXHR, textStatus, errorThrown)
            {
alert("Có lỗi xảy ra!");
            }
        });
    });

Vậy là sau đoạn code đó, mỗi lần bạn gửi đi 1 Ajax, nó sẽ tự động cài crossDomain=true, type="GET" và error thì thông báo như trên, đỡ tốn công viết lại.
3)jQuery.getScript() = $.getScript();
Cái này thì nhìn ví dụ cho lẹ:

PHP Code:

$.getScript("jQuery.js", function(data, textStatus)
    {
alert("Đã load xong jQuery.js");
    });

Hàm trên là cách ghi tắt của:

PHP Code:

$.ajax(
    {
url: "jQuery.js",
dataType: "script",
success: function(data, textStatus)
        {
alert("Đã load xong jQuery.js");
        }
    });

Tuy nhiên, có 1 điều cần lưu ý: Callback [hàm được gọi sau khi load xong script] khi thành công của $.getScript() chỉ bao gồm 2 tham số, trong khi $.ajax bao gồm 3 tham số. Mà thực chất cũng chẳng cần quan tâm, mình đâu cần nó làm gì...
4) jQuery.load() = $.load();
OK, đây là hàm cuối cùng mình đề cập đến, $.load(). Cú pháp của nó như sau:

PHP Code:

$(selector).load(url, <dữ liệu gửi đi, có thể có hoặc ko>, <hàm callback khi load xong function(responseText, textStatus, XMLHttpRequest), có thể có hoặc không>)

Trong đó, url là đường dẫn tới trang cần load, dĩ nhiên rồi, data là dữ liệu gửi đi, cũng giống như jQuery.ajax(), hàm callback khi load xong [chà, y chang jQuery.ajax() còn gì @@). Ví dụ bạn có 1 cái thẻ span như sau:

PHP Code:

<span id="news"></span>

Và bạn muốn dùng nó để load tin tức mới từ 1 trang web khác [news.php chẳng hạn]:

PHP Code:

$(document).ready(function()
    {
    $("#news").load("news.php");
    });

Vậy đó, đơn giản ko. Ủa, thế thì dùng .load() làm gì, dùng $.ajax() luôn ko tiện à? Hay là jQuery quởn quá ngồi chế nhiều hàm cho nó phong phú? Không phải vậy đâu, dùng .load() có những lợi thế mà $.ajax() không có.
Thứ nhất là về mặt "dung lượng":
Một hàm:

PHP Code:

$("#news").load("news.php");

Là viết tắt của hàm:

PHP Code:

$.ajax(
    {
url: "news.php",
success: function(data)
        {
        $("#news").html(data);
        }
    });

Thứ 2, dùng .load() có thể load dc 1 phần của trang thay vì load cả trang, điều mà $.ajax() ko làm được.
Ví dụ bạn chỉ muốn load những tin tức liên quan đến music [được chứa trong id="music" của trang news.php chẳng hạn]:

PHP Code:

$("#news").load("news.php#music");

Thứ 3, có những tính năng như limit load, hay gửi dữ liệu mảng... mà lười lục lại quá nên thôi, cứ dùng cơ bản đi =.='!
BONUS: Dùng Ajax jQuery để đọc XML?
Giả sử bạn có 1 file XML tên là info.xml như sau:

PHP Code:

<info>
    <realname>Nguyễn Huy Trường</realname>
    <birthday>Apr.30.93</birthday>
    <nickname>Timmy Nguyen</nickname>
</info>

Và đây là cách bạn lấy dữ liệu trong đó:

PHP Code:

$.ajax(
    {
type: "GET",
url: "ifno.xml",
dataType: "xml",
success: function(xml)
        {
        $(xml).find("info").each(function()
            {
            var realName=$(this).find("realname").text();
            var birthday=$(this).find("birthday").text();
            var nickName=$(this).find("nickname").text();
            });
        },
error: function(jqXHR, textStatus, errorThrown)
        {
alert("Có lỗi xảy ra!");
        }
    });

Không có gì phức tạp hửh? Đơn giản chỉ là nhận dữ liệu về, rồi quét từng cái có tên được chọn dùng hàm .each(), rồi trong mỗi đợt quét đó tìm ra cái cần lấy dữ liệu và trả về, thế thôi .
[Sưu tầm]