You are on page 1of 21

Căn bản về JavaScript

[Trích từ Wikipedia]

JavaScript, theo phiên bản hiện hành, là một ngôn ngữ lập trình kịch bản dựa trên đối tượng được
phát triển từ các ý niệm nguyên mẫu. Ngôn ngữ này được dùng rộng rãi cho các trang web,
nhưng cũng được dùng để tạo khả năng viết script sử dụng các đối tượng nằm sẵn trong các ứng
dụng. Nó vốn được phát triển bởi Brendan Eich tại Hãng truyền thông Netscape với cái tên đầu
tiên Mocha, rồi sau đó đổi tên thành LiveScript, và cuối cùng thành JavaScript. Giống Java,
JavaScript có cú pháp tương tự C, nhưng nó gần với Self hơn Java. .js là phần mở rộng thường
được dùng cho tập tin mã nguồn JavaScript.

Phiên bản mới nhất của JavaScript là phiên bản 1.5, tương ứng với ECMA-262 bản 3.
ECMAScript là phiên bản chuẩn hóa của JavaScript. Trình duyệt Mozilla phiên bản 1.8 beta 1 có
hỗ trợ không đầy đủ cho E4X - phần mở rộng cho JavaScript hỗ trợ làm việc với XML, được
chuẩn hóa trong ECMA-357.

Java, JavaScript và JScript

Cùng thời điểm Netscape bắt đầu sử dụng công nghệ Java trên trình duyệt Netscape, LiveScript
đã được đổi tên thành JavaScript để được chú ý hơn bởi ngôn ngữ lập trình Java lúc đó đang
được coi là một hiện tượng. JavaScript được bổ sung vào trình duyệt Netscape bắt đầu từ phiên
bản 2.0b3 của trình duyệt này vào tháng 12 năm 1995. Trên thực tế, hai ngôn ngữ lập trình Java
và JavaScript không có liên quan gì đến nhau, ngoại trừ việc cú pháp của cả hai ngôn ngữ cùng
được phát triển dựa trên cú pháp của C. Java Script gồm 2 mảng là client-server thực hiện lệnh
trên máy của end-user và web-server.

Sau thành công của JavaScript, Microsoft bắt đầu phát triển JScript, một ngôn ngữ có cùng ứng
dụng và tương thích với JavaScript. JScript được bổ sung vào trình duyệt Internet Explorer bắt
đầu từ Internet Explorer phiên bản 3.0 được phát hành tháng 8 năm 1996.

DOM (Document Object Model), một khái niệm thường được nhắc đến với JavaScript trên thực
tế không phải là một phần của chuẩn ECMAScript, DOM là một chuẩn riêng biệt có liên quan
chặt chẽ với XML.

Ứng dụng

JavaScript là một ngôn ngữ lập trình dựa trên nguyên mẫu với cú pháp phát triển từ C. Giống
như C, JavaScript có khái niệm từ khóa, do đó, JavaScript gần như không thể được mở rộng.

Cũng giống như C, JavaScript không có bộ xử lý xuất/nhập (input/output) riêng. Trong khi C sử
dụng thư viện xuất/nhập chuẩn, JavaScript dựa vào phần mềm ngôn ngữ được gắn vào để thực
hiện xuất/nhập.

Trên trình duyệt, rất nhiều trang web sử dụng JavaScript để thiết kế trang web động và một số
hiệu ứng hình ảnh thông qua DOM. JavaScript được dùng để thực hiện một số tác vụ không thể
thực hiện được với chỉ HTML như kiểm tra thông tin nhập vào, tự động thay đổi hình ảnh,... Ở
Việt Nam, JavaScript còn được ứng dụng để làm bộ gõ tiếng Việt giống như bộ gõ hiện đang sử
dụng trên trang Wikipedia tiếng Việt. Tuy nhiên, mỗi trình duyệt áp dụng JavaScript khác nhau
và không tuân theo chuẩn W3C DOM, do đó trong rất nhiều trường hợp lập trình viên phải viết
nhiều phiên bản của cùng một đoạn mã nguồn để có thể hoạt động trên nhiều trình duyệt. Một số
công nghệ nổi bật dòng JavaScript để tương tác với DOM bao gồm DHTML, Ajax và SPA.

Bên ngoài trình duyệt, JavaScript có thể được sử dụng trong tập tin PDF của Adobe Acrobat và
Adobe Reader. Điều khiển Dashboard trên hệ điều hành Mac OS X phiên bản 10.4 cũng có sử
dụng JavaScript. Công nghệ kịch bản linh động (active scripting) của Microsoft có hỗ trợ ngôn
ngữ JScript làm một ngôn ngữ kịch bản dùng cho hệ điều hành. JScript .NET là một ngôn ngữ
tương thích với CLI gần giống JScript nhưng có thêm nhiều tính năng lập trình hướng đối tượng.

Mỗi ứng dụng này đều cung cấp mô hình đối tượng riêng cho phép tương tác với môi trường
chủ, với phần lõi là ngôn ngữ lập trình JavaScript gần như giống nhau.
Các thành phần cú pháp chính

Khoảng trắng

Dấu cách, tab và ký tự dòng mới sử dụng bên ngoài một chuỗi ký tự được gọi là khoảng trắng.
Khác với C, khoảng trắng trong JavaScript có thể ảnh hưởng trực tiếp tới ý nghĩa của câu lệnh.
Sử dụng phương pháp "tự động thêm dấu chấm phẩy", bất cứ một dòng JavaScript nào thích hợp
sẽ được coi là một câu lệnh hợp lệ (giống như có dấu chấm phẩy trước ký tự dòng mới).

Tuy trong phần lớn trường hợp, dấu chấm phẩy trước khi kết thúc một dòng JavaScript là không
cần thiết để đoạn mã nguồn hoạt động chính xác, lập trình viên nên sử dụng dấu chấm phẩy sau
mỗi câu lệnh để đoạn mã nguồn dễ nhìn hơn. Ngoài ra, do đặc thù của JavaScript - chuyên dùng
trên trang web, kích cỡ của đoạn mã nguồn là quan trọng, có một số phần mềm có thể làm giảm
kích cỡ của đoạn mã nguồn JavaScript bằng cách bỏ đi những khoảng trắng không cần thiết, để
những phần mềm này hoạt động chính xác, lập trình viên cần thêm dấu chấm phẩy vào cuối mỗi
câu lệnh.

Chú giải

Cú pháp chú giải của JavaScript giống với C++. Lập trình viên có thể chú giải trên nhiều dòng
bằng cách bao bọc chú giải với /* và */ hoặc sử dụng // để chú giải từ vị trí // đến hết dòng.

Biến

Trước khi sử dụng biến trong JavaScript, lập trình viên không nhất thiết phải khai báo biến. Có
hai cách để định nghĩa biến trong JavaScript. Một là sử dụng cú pháp var để khai báo biến:

Code:
<script language="JavaScript">
var tên_biến;
</script>

Ngoài ra, lập trình viên có thể chỉ việc gán cho biến một gía trị để sử dụng biến đó. Biến được
định nghĩa ngoài tất cả các hàm hoặc được sử dụng mà không khai báo với cú pháp var sẽ được
coi là biến toàn cục, những biến này có thể sử dụng trên toàn trang web. Biến được khai báo với
var bên trong một hàm là biến cục bộ của hàm đó và chỉ có thể sử dụng được bên trong hàm đó.

Đối tượng

Kiểu của JavaScript được chia ra làm hai loại: kiểu cơ bản và đối tượng. Đối tượng trong
JavaScript là một thực thể có tên xác định và có thuộc tính trỏ đến giá trị, hàm hoặc cũng có thể
là một đối tượng khác. Có nghĩa là, đối tượng trong JavaScript là một mảng kết hợp (associative
array) tương tự như mảng trong PHP hay từ điển trong Python, PostScript hoặc Smalltalk.

JavaScript có một số đối tượng định nghĩa sẵn, bao gồm mảng (Array), đối tượng đại số Bool
(Boolean), đối tượng ngày tháng (Date), đối tượng hàm (Function), đối tượng toán học (Math),
đối tượng số (Number), đối tượng đối tượng (Object), đối tượng biểu thức tìm kiếm (RegExp) và
đối tượng chuỗi ký tự (String). Các đối tượng khác là đối tượng thuộc phần mềm chủ (phần mềm
áp dụng JavaScript - thường là trình duyệt).

Bằng cách định nghĩa hàm khởi tạo, lập trình viên có thể tạo đối tượng. JavaScript là một ngôn
ngữ lập trình dựa trên nguyên mẫu do đó thừa kế diễn ra giữa các đối tượng, không phải giữa các
lớp (JavaScript không hề có lớp). Đối tượng thừa kế thuộc tính từ các nguyên mẫu của chúng.

Lập trình viên có thể thêm hoặc xóa thuộc tính hoặc hàm trong đối tượng sau khi đối tượng đã
được tạo. Để làm việc này cho tất cả các đối tượng được tạo từ cùng một hàm khởi tạo, lập trình
viên có thể sử dụng thuộc tính prototype của hàm khởi tạo để truy cập đối tượng nguyên mẫu.
Lập trình viên không nhất thiết phải tự xóa các đối tượng đã tạo, JavaScript tự động gom rác tất
cả những biến không còn được dùng nữa.

Ví dụ:

Code:
<script language="JavaScript">
function samplePrototype() {
this.attribute1 = "someValue"; // thêm một thuộc tính cho đối tượng
this.attribute2 = 234; // thêm thuộc tính nữa cho đối tượng
this.function1 = testFunction; // thêm một hàm vào đối tượng
}

function testFunction() {
alert(this.attribute2); //hiển thị 234
}

var sampleObject = new samplePrototype; // khởi tạo một đối tượng


sampleObject.function1(); // gọi hàm function1 của đối tượng sampleObject

sampleObject.attribute3 = 123; // thêm một thuộc tính nữa cho đối tượng
sampleObject

delete sampleObject.attribute1; // xóa bỏ 1 thuộc tính


delete sampleObject; // xóa bỏ đối tượng
</script>
Cấu trúc dữ liệu

Một cấu trúc dữ liệu tiêu điểm là mảng (Array), mảng trong JavaScript là một bảng liên kết chỉ
mục đến giá trị. Trong JavaScript, tất cả các đối tượng đều có thể liên kết chỉ mục đến giá trị,
nhưng mảng là một đối tượng đặc biệt có thêm nhiều tính năng xử lý chỉ mục và dữ liệu đặc biệt
(ví dụ: push, join, v.v.)

Mảng trong JavaScript có thuộc tính length. Thuộc tính length của JavaScript luôn luôn lớn hơn
số chỉ mục lớn nhất trong mảng một đơn vị. Trong phần lớn ngôn ngữ lập trình, những thuộc tính
có tính năng như length thường là thuộc tính chỉ đọc, tuy nhiên, với JavaScript, lập trình viên có
thể thay đổi thuộc tính length. Bằng cách thay đổi thuộc tính length, lập trình viên có thể làm
mảng lớn hơn hoặc nhỏ hơn (và xóa đi những chỉ mục lớn hơn hoặc bằng thuộc tính length mới).

Mảng trong JavaScript là mảng rải rác, có nghĩa là cho dù lập trình viên có một mảng như sau:

Code:
<script language="JavaScript">
var test = new Array();
test[2] = 0;
test[100] = 5;
</script>
Trong trường hợp này, dù mảng có đến chỉ mục mang số 100 thì mảng cũng chỉ chiếm bộ nhớ
của hai số 0 và 5. Tuy nhiên, thuộc tính length sẽ có giá trị 101 do chỉ mục lớn nhất của mảng
trong ví dụ trên là 100.

Một số ví dụ về mảng:

Code:
<script language="JavaScript">
var test = new Array(10); // Tạo một mảng 10 chỉ mục
var test2 = new Array(0,1,2,,3); // Tạo một mảng với bốn giá trị và 5 chỉ
mục
var test3 = new Array();
test3["1"] = 123; // Hoàn toàn đúng cú pháp
</script>

Lập trình viên cũng có thể định nghĩa cấu trúc bằng đối tượng như sau:

Code:
<script language="JavaScript">
var myStructure = {
name: {
first: "Mel",
last: "Smith"
},
age: 33,
hobbies: [ "chess", "jogging" ]
};
</script>
Cú pháp định nghĩa cấu trúc bằng đối tượng trên có một chuẩn trên danh nghĩa là JSON.

Cấu trúc điều khiển

Rẽ nhánh theo điều kiện với if ... else

Cú pháp if ... else dùng trong trường hợp muốn rẽ nhánh theo điều kiện. Cú pháp này tương
đương với nếu x thì làm y, còn nếu không thì làm z. Các câu lệnh if ... else có thể lồng trong
nhau.

Cú pháp:

<script language="JavaScript">
if (biểu_thức_1)
{
khối lệnh được thực hiện nếu biểu thức 1 đúng;
}
else if (biểu_thức_2)
{
khối lệnh được thực hiện nếu biểu thức 2 đúng;
}
else
{
khối lệnh được thực hiện nếu cả hai biểu thức trên đều không đúng;
}
</script>

Ví dụ:

Code:
<script language="JavaScript">
var x = prompt("Nhập vào giá trị của x:");
x = parseFloat(x);

if (!isNaN(x)) {
if (x > 0)
{
alert("x > 0");
}
else if (x == 0)
{
alert("x = 0");
}
else
{
alert("x < 0");
}
}
else
{
alert("giá trị bạn nhập không phải là một số");
}
</script>
Đoạn mã nguồn trên mở một hộp thoại yêu cầu nhập vào một giá trị số, sau đó hiển thị thông báo
số đó lớn hơn 0, bằng 0 hay nhỏ hơn 0.

Code:
Toán tử điều kiện

Toán từ điều kiện còn được biết đến với tên gọi toán tử tam phân. Cú pháp của toán tử này như
sau:

<script language="JavaScript">
điều_kiện ? biểu_thức_đúng : biểu_thức_sai;
</script>

Toán tử này sẽ trả lại giá trị là kết quả của biểu_thức_đúng nếu điều_kiện có giá trị bool bằng
true, ngược lại nó sẽ trả lại giá trị bằng biểu_thức_sai.

Vòng lặp while

Vòng lặp while có mục đích lặp đi lặp lại một khối lệnh nhất định cho đến khi biểu thức điều
kiện trả về false. Khi dùng vòng lặp while phải chú ý tạo lối thoát cho vòng lặp (làm cho biểu
thức điều kiện có giá trị false), nếu không đoạn mã nguồn sẽ rơi vào vòng lặp vô hạn, là một lỗi
lập trình. Vòng lặp while thường được dùng khi lập trình viên không biết chính xác cần lặp bao
nhiêu lần. Cú pháp của vòng lặp while như sau:

Code:
<script language="JavaScript">
while (biểu_thức_điều_kiện) {
khối lệnh cần thực hiện nếu biểu_thức_điều_kiện trả về true;
}
</script>

Vòng lặp do ... while

Về cơ bản, vòng lặp do ... while gần như giống hệt như vòng lặp while. Tuy nhiên, trong trường
hợp biểu thức điều kiện trả về false ngay từ đầu, khối lệnh trong vòng lặp while sẽ không bao giờ
được thực hiện, trong khi đó, vòng lặp do ... while luôn đảm bảo khối lệnh trong vòng lặp được
thực hiện ít nhất một lần. Ví dụ:

Code:
<script language="JavaScript">
while (0 > 1)
{
alert("while"); // Câu lệnh này sẽ không bao giờ được thực hiện
}
do
{
alert("do ... while"); // Bạn sẽ nhận được thông báo do ... while một
lần duy nhất
} while (0 > 1);
</script>

Cú pháp của vòng lặp do ... while như sau:

Code:
<script language="JavaScript">
do
{
khối lệnh;
} while (biểu_thức_điều_kiện);
</script>

Vòng lặp for

Vòng lặp for thường được sử dụng khi cần lặp một khối lệnh mà lập trình viên biết trước sẽ cần
lặp bao nhiêu lần. Cú pháp của vòng lặp for như sau:

Code:
<script language="JavaScript">
for (biểu_thức_khởi_tạo; biểu_thức_điều_kiện; biểu_thức_thay_đổi_giá_trị)
{
Khối lệnh cần lặp;
}
</script>

Khi bắt đầu vòng lặp for, lập trình viên cần khởi tạo một biến nhất định bằng
biểu_thức_khởi_tạo để dùng trong biểu_thức_điều_kiện, nếu biểu_thức_điều_kiện trả về true,
khối lệnh cần lặp sẽ được thực hiện, sau khi thực hiện xong khối lệnh cần lặp,
biểu_thức_thay_đổi_giá_trị sẽ được thực hiện, tiếp theo, biểu_thức_điều_kiện sẽ lại được kiểm
tra, cứ như vậy cho đến khi biểu_thức_điều_kiện trả về false, khi đó vòng lặp sẽ kết thúc.

Vòng lặp for ... in

Vòng lặp for ... in dùng để lặp qua tất cả các thuộc tính của một đối tượng (hay lặp qua tất cả các
phần tử của một mảng). Cú pháp của vòng lặp này như sau:

Code:
<script language="JavaScript">
for (biến in đối_tượng)
{
khối lệnh cần thực hiện, có thể sử dụng đối_tượng[biến] để truy cập
từng thuộc tính (phần tử) của đối tượng;
}
</script>

Cú pháp switch
Cú pháp switch cũng là cú pháp điều kiện như if ... else hay toán tử tam phân. Tuy nhiên, cú
pháp switch thường được dùng khi chỉ cần so sánh bằng với số lượng kết quả cần kiểm tra lớn.
Cách sử dụng cú pháp switch:

Code:
<script language="JavaScript">
switch (biểu_thức_điều_kiện)
{
case kết_quả_1 :
khối lệnh cần thực hiện néu biểu_thức_điều_kiện bằng kết_quả_1;
break;
case kết_quả_2 :
khối lệnh cần thực hiện néu biểu_thức_điều_kiện bằng kết_quả_2;
break;
default :
khối lệnh cần thực hiện nếu biểu_thức_điều_kiện cho ra một kết
quả khác;
}
</script>

Sau mỗi khối lệnh trong một mục kiểm tra kết quả (trừ mục default), lập trình viên cần phải thêm
vào break.

Hàm

Hàm là một khối các câu lệnh với một danh sách một hoặc nhiều đối số (có thể không có đối số)
và thường có tên (mặc dù trong JavaScript hàm không nhất thiết phải có tên). Hàm có thể trả lại
một giá trị. Cú pháp của hàm như sau:
Code:
<script language="JavaScript">
function tên_hàm(đối_số_1, đối_số_2)
{
các câu lệnh cần thực hiện mỗi khi hàm được gọi;
return giá_trị_cần_trả_về;
}

tên_hàm(1, 2); // Gọi hàm tên_hàm với hai đối số 1 và 2 ứng với đối_số_1
và đối_số_2
tên_hàm(1); // Gọi hàm tên_hàm với đối_số_1 có giá trị 1, đối_số_2 có giá
trị undefined
</script>

Trong JavaScript, khi gọi hàm không nhất thiết phải gọi hàm với cùng số đối số như khi định
nghĩa hàm, nếu số đối số ít hơn khi định nghĩa hàm, những đối số không được chuyển cho hàm
sẽ mang giá trị undefined.

Các kiểu cơ bản sẽ được chuyển vào hàm theo giá trị, đối tượng sẽ được chuyển vào hàm theo
tham chiếu.

Hàm là đối tượng hạng nhất trong JavaScript. Tất cả các hàm là đối tượng của nguyên mẫu
Function. Hàm có thể được tạo và dùng trong phép toán gán như bất kỳ một đối tượng nào khác,
và cũng có thể được dùng làm đối số cho các hàm khác. Do đó, JavaScript hỗ trợ hàm cấp độ
cao. Ví dụ:

Code:
<script language="JavaScript">
Array.prototype.fold =
function (value, functor) {
var result = value;
for (var i = 0; i < this.length; i++) {
result = functor(result, this[i]);
}
return result;
}
var sum = [1,2,3,4,5,6,7,8,9,10].fold(0, function (a, b) { return a + b })
</script>

Đoạn mã nguồn trên sẽ trả lại kết quả là 55.

Vì hàm trong JavaScript là đối tượng, lập trình viên có thể khởi tạo hàm không tên:

Code:
<script language="JavaScript">
function() { thân hàm; }
</script>

Một ví dụ sử dụng hàm không tên trong JavaScript:

Code:
<script language="JavaScript">
document.onkeypress = function(e) {
alert("Bạn vừa nhấn một phím trên bàn phím");
}
</script>

Hàm trên sẽ hiển thị thông báo khi một số phím trên bàn phím có thể gây sự kiện onkeypress
được nhấn.

Mặc định, tất cả các thành phần của đối tượng thuộc phạm vi công cộng (public). Trong
JavaScript, không có khái niệm thành phần riêng hay thành phần được bảo vệ (private và
protected), tuy nhiên những tính năng này có thể được giả lập.

Quản lý lỗi

Tùy theo môi trường phát triển, sửa lỗi JavaScript có thể sẽ rất khó khăn. Với JavaScript dùng trên trang
web, hiện tại, các trình duyệt dựa trên Gecko (như Mozilla, Mozilla Firefox) có công cụ tìm diệt lỗi rất tốt
(Venkman), ngoài ra còn kèm theo một công cụ kiểm tra DOM.

Các phiên bản mới hơn của JavaScript (như bản dùng trên Internet Explorer 5 và Netscape 6) hỗ trợ mệnh
đề quản lý lỗi try ... catch ... finally, mệnh đề này bắt nguồn từ Java giúp lập trình viên quản lý lỗi thời
gian chạy hoặc quản lý ngoại lệ xuất phát từ cú pháp throw. Cú pháp của mệnh đề này như sau:

<script language="JavaScript">
try
{
Khối lệnh cần thực hiện có thể gây lỗi;
}
catch (error)
{
Khối lệnh cần thực hiện trong trường hợp có lỗi;
}
finally
{
Khối lệnh luôn được thực hiện;
}
</script>

Trong cú pháp trên error là một đối tượng Error có hai thuộc tính theo chuẩn ECMAScript phiên bản 3:

* error["message"]: Thông điệp diễn giải lỗi


* error["name"]: Tên lỗi

Tuy nhiên mỗi trình duyệt sử dụng một bản JavaScript khác nhau, trong các trình duyệt lớn và phổ dụng
không có trình duyệt nào hoàn toàn tuân thủ theo chuẩn ECMAScript phien bản 3. Ví dụ như Internet
Explorer 6 SP 1 có thêm hai thuộc tính:

* error["number"]: Bí số của lỗi


* error["description"]: Thông điệp diễn giải lỗi

Còn Mozilla Firefox 1.07 có thêm ba thuộc tính:

* error["fileName"]: Tên tập tin xảy ra lỗi


* error["lineNumber"]: Dòng xảy ra lỗi
* error["stack"]: Cả hai thuộc tính trên gộp lại trong một chuỗi ký tự

Phần finally là không bắt buộc. Lập trình viên hoàn toàn có thể sử dụng try ... catch mà không có finally.

Phạm vi ảnh hưởng của lỗi

Các ngôn ngữ lập trình kịch bản rất dễ bị ảnh hưởng bởi lỗi, hơn nữa, mỗi một trình duyệt, mỗi một công
ty ứng dụng JavaScript một cách hoàn toàn khác nhau nên lập trình viên JavaScript thường phải dành rất
nhiều thời gian sửa lỗi để đảm bảo đoạn mã nguồn của mình sẽ hoạt động tốt. Trong những trang HTML
mà thẻ script và các đoạn mã HTML khác xen kẽ lẫn nhau, lỗi cú pháp có thể được phát hiện dễ dàng hơn
bằng cách để mỗi hàm trong một thẻ script riêng biệt hoặc có thể sử dụng nhiều tệp .js khác nhau. Trong
nhiều trường hợp, cách này còn giúp tránh làm hỏng cả trang web trong trường hợp có lỗi trong một đoạn
mã nguồn.

Ajax login form

Bài này hướng dẫn các bạn viết 1 form login bằng Ajax. Mục tiêu không nhằm giới thiệu 1 ajax
framework nào mà viết toàn bộ từ bước cơ bản nhất kỹ thuật Ajax để có thể hiểu sâu Ajax là gì.

1. Tạo form login


Code:
<body>

<!-- Include AJAX Framework -->


<script src="ajax/ajax_framework.js" language="javascript"></script>

<!-- Show Message for AJAX response -->


<div id="login_response"></div>
<div id="divForm">
<!-- Form: the action="javascript:login()"call the javascript function
"login" into ajax_framework.js -->
<form action="javascript:login()" method="post">
<input name="email" type="text" id="emailLogin" value=""/>
<input name="psw" type="password" id="pswLogin" value=""/>
<input type="submit" name="Submit" value="Login"/>
</form>
</div>
</body>

Để ý thấy khi submit, ta dùng một JS function để khởi tạo lời gọi Ajax: login(). Bạn không tìm
thấy đoạn JS cho login() ở đây vì tôi link với 1 file .js bên ngoài tên là ajax-framework.js.

2. Tạo file .js để viết code Ajax


Code:
/* ---------------------------- */
/* XMLHTTPRequest Enable */
/* ---------------------------- */
function createObject() {
var request_type;
var browser = navigator.appName;
if(browser == "Microsoft Internet Explorer"){
request_type = new ActiveXObject("Microsoft.XMLHTTP");
}else{
request_type = new XMLHttpRequest();
}
return request_type;
}

var http = createObject();

/* -------------------------- */
/* LOGIN */
/* -------------------------- */
/* Required: var nocache is a random number to add to request. This value
solve an Internet Explorer cache issue */
var nocache = 0;
function login() {
// Optional: Show a waiting message in the layer with ID ajax_response
document.getElementById('login_response').innerHTML = "Loading..."
// Required: verify that all fileds is not empty. Use encodeURI() to solve
some issues about character encoding.
var email = encodeURI(document.getElementById('emailLogin').value);
var psw = encodeURI(document.getElementById('pswLogin').value);
// Set te random number to add to URL request
nocache = Math.random();
// Pass the login variables like URL variable
http.open('get', 'login.php?email='+email+'&psw='+psw+'&nocache = '+nocache);
http.onreadystatechange = loginReply;
http.send(null);
}
function loginReply() {
if(http.readyState == 4){
var response = http.responseText;
alert(response);
if(response == '0'){
// if login fails
document.getElementById('login_response').innerHTML = 'Login failed! Verify
user and password';
// else if login is ok show a message: "Welcome + the user name".
} else {
document.getElementById('login_response').innerHTML = 'Welcome '+response;
document.getElementById('divForm').style.display = 'none';
}
}
}
Tập trung vào hàm login(), công việc của chúng ta là lấy được dữ liệu nhậu của user thông qua
JS, dùng document.getElementById() để tìm đúng textbox cần lấy giá trị.

Sau đó, ta tạo một chuỗi query string, có thêm một giá trị nocache là giá trị phát sinh random
nhằm chống lại việc trình duyệt cache file login.php, không truyền về server.

Đối tượng http là một đối tượng XMLHTTPRequest, giúp ta gửi 1 request tới server, đối tượng
này tạo ra bởi hàm CreateObject().

Đoạn lệnh mock up này giúp chúng ta biết khi nào nhận được kết quả từ server thì sẽ gọi tiếp
hàm loginReply() để xử lý.
http.onreadystatechange = loginReply;

Sau khi đã đặt thông tin hàm xử lý (gọi là hàm CallBack) thì http.send() sẽ gửi thông tin cần xử
lý tới server. Ở đây, chúng ta gửi tới 1 file chuyên xử lý lời gọi Ajax là login.php

3. Tạo file xử lý lời gọi Ajax


File login.php
Code:
<?php
if(isset($_GET['email']) && isset($_GET['psw'])){

$email = $_GET['email'];
$psw = $_GET['psw'];

if ($email=='hung5s@yahoo.com' && $psw == '123')


echo $email;
else
echo '0';
}
?>

Bạn thấy rằng việc xử lý này cốt trả về một giá trị (hãy coi nó như 1 hàm trả về giá trị) nên ta chỉ
trả về giá trị qua lệnh echo và giá trị đó phải dễ xử lý như là 0 hay $email.

Tiếp theo, function loginReply() xử lý giá trị trả về để hiển thị kết quả.

Bài viết chỉ tới đây để đơn giản cho các bạn thử nghiệm. Reply tiếp theo sẽ phân tích sâu hơn
bản chất của Ajax và về đối tượng XMLHttpRequest.

Viết tiếp ví dụ Ajax login form để chúng ta có khái niệm rõ hơn về một buzz word nổi đình nổi
đám 2 năm nay
AJAX, viết tắt của Asynchronous JavaScript and XML có nghĩa là kỹ thuật lập trình xử dụng
JavaScript làm ngôn ngữ, XML làm công cụ gửi nhận dữ liệu và cơ chế hoạt động gửi nhận dữ
liệu là Không đồng bộ (Asynchronous).

Rứa thì chúng ta thấy rằng trong đống Ajax này chả có gì là PHP ... hợp lý.

Trên thực tế, kỹ thuật lập trình này được sử dụng nhiều trước khi có 1 tên chuẩn AJAX. Bản chất
nó đơn giản là để giải quếyt bài toán sau:

Tôi có 1 web page và một chức năng xử lý (vd là login) cần thực hiện ở server vì lý dó liên quan
tới những resource ở server (như là database về user). Tuy nhiên, tôi lại không muốn user phải
submit nguyên 1 trang web chỉ để xử lý 1 chức năng nho nhỏ trên trang đó. Vậy, tôi phải làm sao
để:

1. Lấy được thông tin cần gửi về server, nhào nặn nó thế nào đó trước khi gửi (vd kiểm tra coi nó
có nhập đầy đủ, đúng format,...)
2. Gửi đống thông tin cần xử lý về server mà không submit webpage
3. Nhận lại kết quả của server một cách âm thầm vì không biết lúc nào server mới trả kết quả về
4. Hiển thị kết quả đó trên webpage cho user.

Bạn thấy rằng có 1 đống việc phải làm trên webpage trong khi nó đang nằm ở browser của người
dùng. Vậy thì chỉ có 1 cách để làm: Code bằng JavaScript (trước khi IE hay FireFox kịp nghĩ ra
cái gì gì script khác nữa cho browser trong tương lai ).
Có công cụ để viết lệnh, vấn đề tiếp theo là định dạng dữ liệu cần truyền là gì. Đương nhiên tới
nay XML là "ngon" nhất cho những dữ liệu phức tạp. Còn dữ liệu đơn giản (như ví dụ login này)
thì chỉ cần text là được.

Vấn đề cuối cùng: 1 đối tựơng JavaScript mà trình duyệt cung cấp để gửi yêu cầu về server mà
không phải submit page. Công cụ này cũng phải biết được quá trình xử lý ở server là gì, lúc nào
xong để còn cho biết mà tiếp tục xử lý result nhận được. Công cụ ta dùng ở đây là
XmlHttpRequest.

Hãy xem lại đoạn code CreateObject() trong file .js ở trên. Vấn đề hơi rối rắm với anh nông dân
chảnh choẹ Microsoft là anh này nhà quê mà hơi khác người, không dùng XmlHttpRequest của
JS mà chơi 1 ActiveX có tên là Microsoft.XMLHTTP. Do vậy mà ai muốn dùng Ajax trên cả
FireFox, IE thì đều phải có đoạn code CreateObject() ở trên.

Như vậy ta có đối tượng chuyên chở (The Transporter) như sau: http = CreateObject();

Tiếp theo là vấn đề gửi data lên server. Chuyện làm sao lấy data ra khỏi mấy cái textbox, ta
không bàn ở đây vì nó rối cả bài Ajax lên.

Xem 3 lệnh sau:


Code:
http.open('get', 'login.php?email='+email+'&psw='+psw+'&nocache = '+nocache);
http.onreadystatechange = loginReply;
http.send(null);

1. Ta chuẩn bị gửi dữ liệu lên server qua lệnh open. Chú ý là đây chỉ là chuẩn bị, chưa gửi đi.
2. Ta phải chỉ ra hàm callback sẽ xử lý kết quả trả về
3. Thực sự bắt đầu việc gửi data và chờ nhận kết quả

Một khi đã gửi, bạn nên biết là hàm callback 'loginReply' sẽ bị gọi liên tục vô số lần cho tới khi
nào kết quả đc server trả về cho webpage. Trong vô số lần bị gọi này, chỉ có 1 lần cần xử lý là
khi dữ liệu đã về tới webpage. Ta tìm ra lần này dựa vào giá trị State của anh chàng transpoter:

http.readyState == 4 <<< xem hàm loginReply()

Cuối cùng, khi đã có dữ liệu, ta lấy nó ra qua thuộc tính responseText hoặc responseXML.

response = http.responseText;

Chú ý là kết quả trả về là toàn bộ nội dung 1 webpage, ở đây là nội dung của trang login.php. Vì
thế bạn phải kiểm tra trang này để nội dung trả về như mong muốn. Cẩn thận với những đoạn
code nằm ngoài <?php ?> vì nó sẽ bị trả về cho hàm CallBack luôn.
Cuối cùng, đã có dữ liệu trả về, ta xử lý và hiển thị kết quả. Đoạn code xử lý trong ví dụ dùng
một kỹ thuật DHTML (hay JS + CSS) để dấu đi cái form login và hiện ra chữ welcome ...

Trong ví dụ trên, nếu bạn để ý thì http.open dùng phương thức GET để gửi data về server.
Đương nhiên webpage hoạt động "thầm lặng" nên bạn không bị lộ password trên thanh address
bar. Nhưng nếu dùng 1 tool để tracing các HTTP request (FireFox có cung cấp) thì chắc chắn sẽ
thấy.

Nhu cầu khác cần gửi data bằng Post là giả sử cái form của ta chứa một textarea cho phép user
nhập vào 1 văn bản dài vô thiên ủng. GET không kham nổi data qúa dài nên ta phải dùng post.

Đây là đoạn code modify lại để dùng POST khi send data:

Code:
http.open('post', 'login.php?nocache = '+nocache);
http.setRequestHeader('Content-type', 'application/x-www-form-
urlencoded;charset=UTF-8;');
http.onreadystatechange = loginReply;
http.send('email='+email+'&psw='+psw);

Tôi vẫn để nocache trên query string vì browser căn cứ vào URL chứ không phải data để cache
và xử lý request của user.

Chú ý là nếu muốn test, bạn phải vào sửa trang login.php thay _GET bằng _POST.

Một số service phục vụ Ajax hay feed bây giờ theo "xu thế chung" của thời đại, có thêm các trả
về dữ liệu dùng JSON thay cho XML. Dùng cách này, service sẽ hỗ trợ Ajax của bạn gọi cross
site, ví dụ service của Yahoo là support data bằng JSON.

Đại để về format JSON data của service: http://abc.com/service.php?


callback=json_callback_function.

Cái Service.php bình thường có thể trả về XML data, nhưng khi thấy có tham số callback thì sẽ
format data theo JSON và trả về. Khi trả dữ liệu về dạng này, JSON có thể được dùng để xử lý
data.

Kỹ thuật này thực ra không còn gọi là AJAX chuẩn nữa vì viết code JS theo JSON (JavaScript
Object Notation).
Với kỹ thuật này, thay vì dùng XmlHttpRequest, bạn phải dùng JSON để add <script> tag vào
<head> để gọi web service ở domain kia.
Code:
function dyna_script(url){
var script=document.createElement('script');
script.src=url; // sets the scripts source to the specified url
script.type="text/javascript";

document.getElementsByTagName('head')[0].appendChild(script); }
Lúc này, lời gọi Web servirce tức là URL truyền vô hàm này chính là cái URL trên, có tham số
callback.

Đây chỉ là cội nguồn của sự sống, hiện giờ jQuery đã support vụ này nên cứ coi như AJAX
chuẩn của jQuery mà dùng xả láng. Prototype cũng có plugin hỗ trợ.

XML, XML NS và XML Schema

XML (Extensible Markup Language) là ngôn ngữ đánh dấu mở rộng được phát triển dựa trên
tính đơn giản, dễ dùng của HTML và tính phức tạp nhưng đa chức năng của SGML. XML được
thiết kế để cho phép máy tính có thể trao đổi tài liệu với nhau thông qua Web mà không làm mất
đi ý nghĩa của dữ liệu.
Một tài liệu XML bao gồm một tập các cặp thẻ được lồng vào nhau. Mỗi thẻ có một cặp các
thuộc tính và giá trị.
Ví dụ:
<Students>
<name>Lê Nguyên Sinh</name>
<from>Trung tâm CNTT, ĐHSP Hà Nội</from>
</ Students>

Cấu trúc của một tài liệu XML:

Một tài liệu XML có thể được chia thành hai phần chính, mỗi phần có thể có các thành phần theo
quy định khác nhau:
- Phần Prolog: Chứa các khai báo cho tài liệu XML. Phần này có thể chứa các định đạng như:
Các chỉ thị xử lý, định nghĩa kiểu cho tài liệu, chú thích, phiên bản đang sử dụng, cách thức mã
hóa dữ liệu, báo cáo các chỉ thị xử lý cho ứng dụng.
- Phần thân chứa nội dung dữ liệu, bao gồm một hay nhiều phần tử, mỗi phần tử được chứa trong
một cặp thẻ. Phần tử đầu tiên của tài liệu được gọi là phần tử gốc (root element).
Một tài liệu XML được coi là hợp khuôn dạng (well-form) nếu nó tuân thủ các quy tắc sau:
•Các khai báo XML cần được đặt tại dòng đầu tiên của tài liệu, chẳng hạn như khai báo phiên
bản hay các chỉ thị xử lý XML.
•Mỗi tài liệu XML chỉ có một thành phần gốc (root) chứa mọi thành phần khác trong tài liệu.
Các thành phần có thể đứng trước phần tử gốc là chú thích, chỉ thị xử lý và định nghĩa DTD (nếu
khai báo ở phần khởi đầu của tài liệu).
•Mỗi phần tử của tài liệu phải được nằm trong một cặp thẻ. Nếu là phần tử rỗng thì thẻ phải được
kết thúc bằng "/>". Ví dụ: "<image/>"
•Các thành phần trong tài liệu XML, khác thành phần gốc đều nằm giữa cặp thẻ gốc và phải lồng
nhau một cách hợp lý, tức là không có thành phần phủ, tập hợp thẻ này không được phép chồng
lên thẻ kia, mỗi tập trong phải nằm trong tập hợp lớn hơn kế tiếp.
•Các cặp thẻ phải được viết chính xác như nhau kể cả chữ hoa hay chữ thường.
•Các giá trị của các thuộc tính đều phải nằm giữa hai ngoặc kép. Ví dụ: hide=true là không hợp
lệ, mà phải là hide="true".
XML NS
NS (Namespace) có nghĩa là không gian tên, một khái niệm được dùng để chỉ không gian tên trong một
tài liệu XML (XML Namespace)

Không gian tên XML là một chuẩn của W3C để cung cấp các phần tử với tên và thuộc tính duy nhất trong
một thể hiện XML. Một thể hiện XML có thể chứa tên các thuộc tính hoặc tên các phần tử từ nhiều bộ từ
vựng XML. Nếu các bộ từ vựng này được cung cấp bởi một NS thì sự nhập nhằng trong việc định danh
giữa các phần tử hoặc thuộc tính có thể được giải quyết.

Tất cả các tên các phần tử trong cùng một NS phải là đơn nhất.

Hãy xem xét một ví dụ về một thể hiện XML trong đó có chứa tham chiếu đến một customer và một
product. Cả hai thành phần customer và product đều có thể có một thành phần con là “ID_number”. Vì
vậy, khi tham chiếu tới thành phần ID_number có thể sẽ gây ra sự nhập nhằng, trừ phi các phần tử được
đặt cùng định danh nhưng khác ý nghĩa được sinh ra dưới các NS cho phép phân biệt chúng.

Một NS được khai báo bằng cách sử dụng thuộc tính XML dành riêng xmlns, giá trị của nó phải là sự
tham chiếu tới một URI. Ví dụ:
xmlns="http://www.w3.org/1999/xhtml"

Trong thực tế, địa chỉ URI có thể không thực sự được đọc. Nhiều bộ phân tích XML coi nó như là một
chuỗi đơn thuần. Ví dụ: bản thân http://www.w3.org/1999/xhtml không chứa bất kỳ đoạn mã nào, nó chỉ
mô tả NS xhtml dành cho người đọc. Việc sử dụng URI để định nghĩa một NS (đúng hơn là một chuỗi
đơn giản) sẽ làm giảm khả năng các NS khác nhau sử dụng các bộ định danh trùng nhau.

Sự khai báo có thể bao gồm một tiền tố ngắn cùng với mỗi phần tử và thuộc tính có thể được định danh,
ví dụ:
xmlns:xhtml=http://www.w3.org/1999/xhtml

XML Schema
XML Schema là một tài liệu XML được viết dưới dạng thức thuần văn bản với phần mở rộng .xsd. Tài
liệu này mở đầu bằng khai báo chuẩn XML, tiếp theo dùng tiếp đầu ngữ xsd: để khai báo không gian tên
XML Schema, theo cú pháp sau :
<?xml version = “1.0” ?>
<xsd:schema xmlns:xsd = http : // www.w3.org/1999/XMLSchema>
………….....
</xsd:schema>
Để chương trình xử lý XML có thể sử dụng tập tin lược đồ (.xsd) cho tài liệu XML, thì các bộ xử lý
phải có cách cài đặt cụ thể của riêng nó để nhận ra lược đồ đi kèm với tài liệu XML. W3C cho phép khai
báo không gian tên cho tài liệu XML tham chiếu đến tập tin lược đồ theo địa chỉ URL như sau :
<?xml version = “1.0” ?>
<rootElement xmlns = “URL”>
………..
</rootElement>
XML Schema được Microsoft đề xuất để thay thế cho định kiểu tư liệu (Document Type Definition -
DTD), được sử dụng để định nghĩa kiểu tư liệu cho các phần tử XML, vốn xuất thân từ SGML, khó sử
dụng và có một số nhược điểm như không định nghĩa chính xác được các loại dữ liệu. XML Schema có
một số ưu điểm:
• Dễ học và dễ dùng hơn DTD
• Định nghĩa chính xác được các kiểu dữ kiện (data type)
• Có hệ thống không gian tên (NS) tốt hơn
• Dùng lại được các phần tử bằng cách thừa kế

Công nghệ XML đã làm nên một cuộc cách mạng lớn trong ngành công nghiệp phần mềm. Vì tính tiện
dụng của nó, XML được sử dụng để chuẩn hóa các dạng dữ liệu với nhau, tạo điều kiện cho các chương
trình máy tính trao đổi dữ liệu với nhau một cách dễ dàng qua các dữ liệu được chuẩn hóa. Nhờ vậy, dữ
liệu được sử dụng một cách hiệu quả hơn, được trao đổi và tái sử dụng ở nhiều nơi mà không cần sử dụng
đến các thao tác copy, paste của con người

Các chuẩn truyền thông nổi đình nổi đám được xây dựng bằng XML có thể kể đến chuẩn Dublin Core -
một chuẩn lõi chỉ có khoảng 15 phần tử để định nghĩa các thuộc tính liên quan đến một tài liệu nào đó.
Chuẩn này được ứng dụng rất nhiều trong các ngành công nghiệp phần mềm, và là cơ sở để người ta phát
triển nên các chuẩn khác. Một chuẩn nữa được xây dựng dựa trên XML đã từng làm mờ mắt hàng triệu
người dùng Internet là chuẩn định dạng RSS, chuẩn này đã làm nên một cuộc cách mạng lớn trên Internet
với sự ra đời của các trang tin tức, blog... mà qua đó người ta có thể trao đổi với nhau chỉ bằng vài cái
kích chuột.

Trước khi đi vào RDF, tôi sẽ trình bày lại một số kỹ thuật xử lý XML bằng PHP, bao gồm những thao tác
căn bản nhất đề truy xuất XML, cho đến việc ứng dụng những thao tác này để tách chiết thông tin từ
những trang tin tức hỗ trợ RSS.

PHP5 cung cấp class SimpleXML là một class rất dễ sử dụng, bài này sẽ hướng dẫn các bạn
parse file XML trong 7 nốt nhạc.

Đầu tiên, lấy một đoạn XML mẫu để tập tành phân tích:
Code:
<?xml version="1.0"?>
<books>
<book isbn="978-1594489501">
<title>A Thousand Splendid Suns</title>
<author>Khaled Hosseini</author>
<publisher>Riverhead Hardcover</publisher>
<amazon_price>14.27</amazon_price>
</book>
<book isbn="978-1594489587">
<title>The Brief Wondrous Life of Oscar Wao</title>
<author>Junot Diaz</author>
<publisher>Riverhead Hardcover</publisher>
<amazon_price>14.97</amazon_price>
</book>
<book isbn="978-0545010221">
<title>Harry Potter and the Deathly Hallows</title>
<author>J. K. Rowling</author>
<publisher>Arthur A. Levine Books</publisher>
<amazon_price>19.24</amazon_price>
</book>
</books>
Để tạo ra một đối tượng SimpleXmlElement, cách đơn giản là truyền vào một chuỗi hoặc một
file:

Code:
// Passing the XML
$books = SimpleXMLElement($XmlData);
//-------------------
// Passing a filename
$books = SimpleXMLElement('books.xml', null, true);

Nhìn vào đoạn XML ví dụ, ta sẽ lấy ra tất cả các book hay của Amazon:
Code:
<?php
// load SimpleXML
$books = new SimpleXMLElement('books.xml', null, true);

echo <<<EOF
<table>
<tr>
<th>Title</th>
<th>Author</th>
<th>Publisher</th>
<th>Price at Amazon.com</th>
<th>ISBN</th>
</tr>

EOF;
foreach($books as $book) // loop through our books
{
echo <<<EOF
<tr>
<td>{$book->title}</td>
<td>{$book->author}</td>
<td>{$book->publisher}</td>
<td>${$book->amazon_price}</td>
<td>{$book['isbn']}</td>
</tr>

EOF;
}
echo '</table>';
?>
Bạn để ý rằng $books (có chữ 's' nhé) là một Element do khái niệm mỗi một file XML thì phải có
root element. Vì thế, đừng mong đợi có đối tượng SimpleXml không nhé . Mỗi element có thể
có nhiều element con cùng loại hay khác loại, ví dụ này là cùng loại 'book' và class
SimpleXmlElement này cho phép ta duyệt qua các element con cùng loại như một array như ví
dụ foreach() ở trên.

Cuối cùng, nói về cú pháp truy cập child element và attribute. Bác nào chưa biết khái niệm này
nữa thì:
Code:
<book isbn="978-1594489501">
<title>A Thousand Splendid Suns</title>
<author>Khaled Hosseini</author>
<publisher>Riverhead Hardcover</publisher>
<amazon_price>14.27</amazon_price>
</book>

isbn là một attribute, các giá trị của một attribute phải để trong dấu (")
<title>, <author>,... là các child element

Chỉ giải thích tới đây thôi, bác nào có ý định ngâm cứu XML, XML Schema,... thì 5s gợi ý là
nên ... từ bỏ ý định ngông cuống thừa thời gian này đi vì có cả năm may ra học mới xong mà
học từ tháng 1-12 thì tới tháng 12 sẽ quên tháng 1 . Cứ việc coi nó như khái niểm HTML đã
học rồi xài cho thoải mái nhá.

Quay về cú pháp, lại coi ví dụ 'simple' trên: $book->title là truy cập child element trong khi
$book['isbn'] là truy cập attribute. Done!!!

Đơn giản thế thôi, bạn thấy xử lý XML data có dễ chưa ?

Ví dụ trên, nếu bạn không thích dụng foreach thì có thể dùng biến counter $i, viết lại là
$tempBook = $books->book[$i] rồi dùng $tempBook để xử lý.

Giờ thêm vào tí XPath cho nó bằng anh bằng em:

XPath đơn giản là cách chỉ ra đường dẫn "path" trong 1 XML document thông qua các element
cha/con theo cú pháp giống như thư mục của linux: /home/user/... Xpath giúp bạn lọc ra các
child element trong các element cha cùng loại, gom lại thành mảng và xử lý.

Ví dụ sau giúp bạn lấy ra tất cả các title của book và tất cả các số ISBN:
Code:
$titles = $books->xpath('book/title');
foreach($titles as $title)
{
echo $title.PHP_EOL;
}
//////////////////////////////////////////////
$isbn = $books->xpath('book/@isbn');
foreach($isbn as $isbn)
{
echo $isbn.PHP_EOL;
}

Nhớ chú ý cách dùng cú pháp / và /@ nhé.

Giờ parse thử RSS của tuổi trẻ coi sao nè


Code:
<?php
$rss = new SimpleXMLElement('http://www.tuoitre.com.vn/tianyon/RssView.aspx?
ChannelID=16', null, true);

echo "<h1><a href='{$rss->channel->link}'>{$rss->channel-


>title}</a></h1>".PHP_EOL.'<hr />'.PHP_EOL;

foreach($rss->xpath('channel/item') as $item)
{
echo <<<EOF
<h2><a href='{$item->link}'>{$item->title}</a></h2>
<div>Posted at: {$item->pubDate}</div>
{$item->description}
<hr />

EOF;
}
?>

Cuối cùng,một vài thuộc tính của đối tượng SimpleXmlElement các bạn sẽ quan tâm:
$value = trim((string) $element); // Bản thên element nó là XML, bạn lấy giá trị của
element thì ép kiểu về string
$attributes = $element->attributes(); // lấy tất cả các attribute
$children = $element->children(); // lấy các child element

You might also like