P H P  V I E T  N A M  P O R T A L
Xin chào, Khách. Vui lòng đăng nhập hoặc đăng ký tài khoản.
Bạn đã quên email kích hoạt?






     Trang chủ | Download | Tự học PHP | Kho tư liệu | Diễn đàn
Trang: [1] 2
  In  
Current Topic Rating: ****
You have not rated this topic. Select a rating:
Tác giảChủ đề: Ajax login form  (Đã đọc 86496 lần)
phpKungFu
For a better united PHP community in Vietnam
Administrator
PHP Intermediate
*****
Posts: 418


Flattern the world


Xem hồ sơ WWW
« on: January 15, 2008, 11:08:28 PM »

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.
« Last Edit: January 16, 2008, 08:55:38 AM bởi hung5s » Logged

Twitter: http://twitter.com/phpKungFu
-------------------------------------
Flexica Solutions
http://www.webflexica.com
doangia
Administrator
PHP Intermediate
*****
Posts: 1097

Hữu Tâm Ắt Thành Tựu


Xem hồ sơ WWW Email
« Trả lời #1 on: January 16, 2008, 01:59:57 AM »

Em hỏi nhỏ nhá :
Code:
http.onreadystatechange = loginReply;
Làm thế nào để truyền cho hàm handle response 1 tham số nhỉ ? Ví dụ em muốn truyền cho nó cái ID của element sẽ show cái response này . Em thử
Code:
http.onreadystatechange = loginReply('test');
Bên dưới là
Code:
function loginReply(ID){
document.getElementById(ID).innerHTML = 'Welcome '+response;
}
// dzâng dzâng

 Em phải làm sao ? Em thấy nhiều framework Ajax làm được vụ này nhưng em chưa dùng FW bao giờ , chỉ đơn sơ thế này nên không biết rõ .
Logged

Cần Thơ Gạo Trắng Nước Trong
Đến Chơi Mang Dép Chân Không Đi Về ...
phpKungFu
For a better united PHP community in Vietnam
Administrator
PHP Intermediate
*****
Posts: 418


Flattern the world


Xem hồ sơ WWW
« Trả lời #2 on: January 16, 2008, 02:09:55 AM »

Nguyên tắc callback chỉ truyền tên hàm, không bao giờ truyền tham số.

Framework ajax hoàn toàn triển khai theo cách riêng của nó bạn ạh.
Logged

Twitter: http://twitter.com/phpKungFu
-------------------------------------
Flexica Solutions
http://www.webflexica.com
phpKungFu
For a better united PHP community in Vietnam
Administrator
PHP Intermediate
*****
Posts: 418


Flattern the world


Xem hồ sơ WWW
« Trả lời #3 on: January 16, 2008, 09:22:14 AM »

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 Grin
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 Grin... 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 Grin).

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 ...
Logged

Twitter: http://twitter.com/phpKungFu
-------------------------------------
Flexica Solutions
http://www.webflexica.com
phpKungFu
For a better united PHP community in Vietnam
Administrator
PHP Intermediate
*****
Posts: 418


Flattern the world


Xem hồ sơ WWW
« Trả lời #4 on: January 16, 2008, 09:37:27 AM »

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.
Logged

Twitter: http://twitter.com/phpKungFu
-------------------------------------
Flexica Solutions
http://www.webflexica.com
cmxq
Administrator
PHP Intermediate
*****
Posts: 1330


Xem hồ sơ Email
« Trả lời #5 on: January 17, 2008, 10:31:29 AM »

Các cậu có cách nào để sử dụng Ajax lấy dữ liệu từ một trang Web khác tên miền không? Ngày xưa có một lần tớ hùng hổ làm cái này, kết quả thất bại thảm hại Sad
Logged

Trở về phpvn.org
phpKungFu
For a better united PHP community in Vietnam
Administrator
PHP Intermediate
*****
Posts: 418


Flattern the world


Xem hồ sơ WWW
« Trả lời #6 on: January 17, 2008, 11:19:01 AM »

Về bản chất, tất cả các web browser đều cấm các request theo kiểu cross-domain tức là webpage là của một domain khác nhưng lại muốn lấy data từ 1 domain khác nữa.

Flash có nhiều nhu cầu về cross-domain nên nghĩ ra 1 trò gọi là crossdomain.xml trên server từ đó cho phép trusted domains gọi lẫn nhau qua flash

Với Ajax muốn tay không bắt giặc thì phải có một chút mánh là dùng web proxy. Vì đã biết resource xử lý lời gọi ajax ở domain kia là gì, trả về kết quả gì, bác viết lại 1 file gọi resource đó từ web server của bác. Có lẽ dùng cURL là ngon lành cho vụ này, ở đây web server của bác bị hạ bệ một chút thành web client Cheesy

Tiếp theo, khi có được data rồi, thì nân cấp nó lại thành web server bằng cách parse data ra rồi trả về cho ajax. Lúc này ajax đã gọi cái proxy nằm trên server của bác rồi nên nó cùng domain, Browser chịu thua không cấm được nữa.
Logged

Twitter: http://twitter.com/phpKungFu
-------------------------------------
Flexica Solutions
http://www.webflexica.com
phpKungFu
For a better united PHP community in Vietnam
Administrator
PHP Intermediate
*****
Posts: 418


Flattern the world


Xem hồ sơ WWW
« Trả lời #7 on: January 17, 2008, 11:42:21 AM »

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ợ.

Tớ yêu cả 2 thằng Prototype và jQuery. Không biết có bác nào tận tâm hơn viết cho tớ 1 bài tut về JSON nhỉ. Grin đa tạ.
Logged

Twitter: http://twitter.com/phpKungFu
-------------------------------------
Flexica Solutions
http://www.webflexica.com
cmxq
Administrator
PHP Intermediate
*****
Posts: 1330


Xem hồ sơ Email
« Trả lời #8 on: January 17, 2008, 06:07:50 PM »

Grin Cái tớ muốn là sử dụng javascript + ajax để giảm gánh nặng cross site cho server, nhưng mà tự dưng hôm qua tớ lại nghĩ ra được cách khác để vượt qua trở ngại này rồi, có điều cần phải thử một tí đã Grin
Logged

Trở về phpvn.org
mxtdn
PHP Starter
*
Posts: 4


Xem hồ sơ Email
« Trả lời #9 on: March 19, 2008, 09:21:03 PM »

Tớ giới thiệu bạn 1 website rất hay về ajax, bài viết rất cụ thể, ví dụ đơn giản và dễ hiểu, có trích dẫn trong mỗi function, .... All in one:
AJAX - Tương lai của ứng dụng Web
http://www.nguoitapviet.info/2005/06/16/183/

Ví dụ đc đính kèm trong bài viết.
Logged
fcmtuan
PHP Starter
*
Posts: 26



Xem hồ sơ Email
« Trả lời #10 on: August 02, 2008, 08:31:06 PM »

thks anh nha, bài viết tương đối dễ hiểu. Nhưng anh có thể cho thêm ví dụ dc ko
Logged

fcmtuan
PHP Starter
*
Posts: 26



Xem hồ sơ Email
« Trả lời #11 on: August 02, 2008, 10:34:11 PM »

xin bổ sung cái readyState ở trên. Tại lúc đầu t đọc k hiểu cái readyState tại sao lại = 4 nên search google, cho kết quả như sau
State       Description
0   The request is not initialized
1   The request has been set up
2   The request has been sent
3   The request is in process
4   The request is complete
Logged

phpKungFu
For a better united PHP community in Vietnam
Administrator
PHP Intermediate
*****
Posts: 418


Flattern the world


Xem hồ sơ WWW
« Trả lời #12 on: August 03, 2008, 06:52:46 AM »

Thanks fcmtuan Wink
Logged

Twitter: http://twitter.com/phpKungFu
-------------------------------------
Flexica Solutions
http://www.webflexica.com
fcmtuan
PHP Starter
*
Posts: 26



Xem hồ sơ Email
« Trả lời #13 on: September 24, 2008, 03:03:10 AM »

Trong bt của mình, cái readyStatus của đã trả về 4 rồi, nhưng không hiểu sao cái status lại là 404 (không tìm thấy file). Lỗi này có thể bị ở chỗ nào nhỉ
Logged

ngonchan
PHP Intermediate
*
Posts: 122

ngon.chan
Xem hồ sơ WWW Email
« Trả lời #14 on: September 24, 2008, 10:19:36 PM »

Trong bt của mình, cái readyStatus của đã trả về 4 rồi, nhưng không hiểu sao cái status lại là 404 (không tìm thấy file). Lỗi này có thể bị ở chỗ nào nhỉ
  Bạn xem lại biến url được truyền cho hàm open() thử xem, có khi đường dẫn trong url này sai nên status trả về là 404 (status = 404 -> có trả về dữ liệu nên lúc này readyState vẫn là 4 - complete).
Logged
Trang: [1] 2
  In  
 
Chuyển sang:  

Powered by SMF 1.1.15 | SMF © 2006-2007, Simple Machines . Modified by PHPVN Members