Tải bản đầy đủ (.doc) (10 trang)

Hướng dẫn lập trình web bằng ASP.NET pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (203.59 KB, 10 trang )

Hướng dẫn lập trình web bằng ASP.NET
Project1: ONLINE CLASS VIEWER
Tài liệu hướng dẫn – Kỹ thuật AJAX
1. Giới thiệu
Bình thường, mỗi khi browser gởi 1 yêu cầu lên server thì nó phải reload lại trang web, tức là
yêu cầu server gửi lại toàn bộ trang web.
Kĩ thuật Ajax (Asynchronous Javascript And Xml) giúp cho browser có thể gửi yêu cầu đến
server và nhận response mà không cần reload lại trang web. Ngoài ra, request này có thể được
thực hiện 1 cách bất đồng bộ ( trong quá trình thực hiện request, người dùng vẫn có thể tương
tác với trang web)
Kĩ thuật này sử dụng đối tượng XMLHttp để thực hiện các truy vấn lên server.
2. Sử dụng lớp XMLHttp
Ta sẽ sử dụng javascript để thao tác trên đối tượng XMLHttp.
2.1. Tạo đối tượng XMLHttp:
Bước đầu tiên cần phải thực hiện trong việc sử dụng đối tượng XMLHttp là phải tạo nó.
Đối với các trình duyệt khác nhau thì việc tạo đối tượng này sẽ khác nhau.
Đối với Internet Explorer (IE), đối tượng này được cài đặt dưới dạng 1 ActiveXObject.
Do đó, để tạo được nó, cần phải thực hiện câu lệnh javascript sau:
var oXmlHttp = new ActiveXObject("Microsoft.XMLHttp");
Trong đó Microsoft.XMLHttp là loại đối tượng ActiveXObject cần tạo.
Tuy nhiên, có nhiều phiên bản IE khác nhau nên để đối tượng XMLHttp cũng có nhiều
phiên bản khác nhau.
Các phiên bản này là:
• Microsoft.XMLHttp
• MSXML2.XMLHttp
• MSXML2.XMLHttp.3.0
• MSXML2.XMLHttp.4.0
• MSXML2.XMLHttp.5.0
Để viết 1 đoạn code tổng quát, có thể sử dụng cho bất kì phiên bản IE nào, ta sẽ dùng câu
lệnh try … catch
Bộ môn HTTT- Khoa CNTT


Hướng dẫn lập trình web bằng ASP.NET
Đối với các trình duyệt : Mozilla Firefox, Safari, và Opera thì câu lệnh javascript để tạo
đối tượng XMLHttp giống nhau:
var oXmlHttp = new XMLHttpRequest();
Như vậy, để tạo được đối tượng XMLHttp cho mọi trình duyệt ta dùng đoạn javascript
sau:
Bộ môn HTTT- Khoa CNTT
Hướng dẫn lập trình web bằng ASP.NET
2.2. Sử dụng đói tượng XMLHttp
Sau khi đã tạo đối tượng XMLHttp, ta bắt đầu thực hiện việc tạo request đến server.
Bước đầu tiên là gọi phương thức open, dùng để khởi tạo đối tượng. Phương thức này
nhận vào 3 tham số:
• Request Type: là 1 chuỗi cho biết loại request cần thực hiện, có thể là GET hoặc
POST.
• URL: là chuỗi URL cho biết địa chỉ cần gởi request đến.
• Async: là 1 giá trị boolean, cho biết request có được thực hiện 1 cách bất đồng bộ
hay không.
Tham số này rất quan trọng, nó xác định cách thức mà javascript thực hiện request. Khi
được thiết lập là true, request sẽ được thực hiện 1 cách bất đồng bộ, và các đoạn lệnh
javascript vẫn tiếp tục được thực hiện mà không cần phải chờ response từ server. Vì vậy,
ta cần phải cài đặt 1 hàm xử lí sự kiện có nhiệm vụ chờ response từ server. Nếu async là
false thì các đoạn lệnh javascript kế tiếp sẽ không được thực hiện cho đến khi server gởi
xong dữ liệu về. Nếu như thời gian mà server trả response về là lâu thì sẽ gây bất tiện vì
người dùng không thể tương tác được với trang web trong khoảng thời gian đó. Vì vậy,
cách tốt nhất là gán cho async giá trị True khi gọi hàm open.
Ví dụ: Để thực hiện 1 request yêu cầu server trả về nội dung file info.txt nằm trên thư
mục chứa trang web trên server thì ta thực hiện như sau:
oXmlHttp.open("get", "info.txt", true);
Đối tượng XMLHttp có 1 thuộc tính là readyState, tham số này sẽ thay đổi khi mà
request được thực hiện và khi client nhận được response từ server. Thuộc tính này có 5

giá trị như sau:
• 0 (Uninitialized): Đối tượng mới đựơc tạo nhưng hàm open chưa được gọi.
• 1 (Loading): Hàm open mới được gọi nhưng request chưa được gởi
• 2 (Loaded): Request vừa mới được gởi
• 3 (Interactive): Client đã nhận được một phần response từ server
• 4 (Complete): Tất cả dữ liệu đã được server gởi về client và kết nối đã đóng lại.
Mỗi lần thuộc tính readyState thay đổi giá trị thì sự kiện readystatechange được phát
sinh và hàm xử lí sự kiện onreadystatechange được gọi. Do các browser cài đặt đối
tượng XMLHttp khác nhau nên để đảm bảo trang web của mình có thể chạy được trên
nhiều browser thì ta chỉ nên dùng các giá trị sau của thuộc tính readyState: 0, 1 và 4
Trong hầu hết các trường hợp, ta chỉ cần xét trường hợp thuộc tính readyState có giá trị là
4, tức là khi toàn bộ dữ liệu từ server đã gởi đến client.
Bộ môn HTTT- Khoa CNTT
Hướng dẫn lập trình web bằng ASP.NET
Trong đoạn lệnh ở trên, ta định nghĩa 1 hàm onreadystatechange có chức năng hiển thị 1
dialog box để thông báo.
Bước cuối cùng là gọi hàm send(), hàm này sẽ thực sự gởi request lên server. Hàm này
có 1 tham số, đó là chuỗi chứa phần body của request. Đối với request loại GET thì
không cần phần body này, do đó, ta gọi hàm send với tham số là NULL. Đối với loại
request là POST thì tham số này khác null.
oXmlHttp.send(null);
Sau khi gọi hàm này thì request được gởi đi, khi toàn bộ dữ liệu được nhận về thì hàm
onreadystatechange sẽ được gọi và ở đây, ta sẽ thực hiện các xử lí tương ứng với dữ
liệu nhận được. Dữ liệu này được lấy thông qua 1 trong 2 thuộc tính responseText hoặc
responseXML.
Thuộc tính responseText chứa chuỗi response trong khi responseXML chứa 1 đối tượng
tài liệu XML. Thuộc tính responseXML chỉ được dùng khi loại dữ liệu trả về là text/xml.
Trong trường hợp yêu cầu nội dung file info.txt trong ví dụ trên thì ta chỉ cần dùng thuộc
tính responseText.
Nếu sử dụng thuộc tính responseXML thì cần tìm hiểu thêm về DOMDocument vì

responseXML chính là 1 đối tượng DOMDocument. Có thể tìm thông tin về loại đối
tượng này trong MSDN 2003 với từ khóa “DOMDocument”.
Một đoạn code ví dụ sử dụng thuộc tính responseXML
var xmldoc = httpRequest.responseXML;
var root_node = xmldoc.getElementsByTagName(root).item(0);
alert(root_node.firstChild.data);
• Các vấn đề khác
Một vấn đề nữa được đặt ra là, sau khi thực hiện, có thể request không thành công. Chẳng
hạn như, nếu ta yêu cầu server trả về nội dung file info.txt nhưng trên server không có
file này thì lỗi sẽ phát sinh.
Để giải quyết trường hợp bị lỗi, ta dùng 2 thuộc tính khác của lớp XMLHttp là status và
statusText. Nếu status có giá trị là 200 thì request thành công, ngược lại, request thất
bại, khi đó, thông tin lỗi sẽ được chứa trong thuộc tính statusText.
Sau khi nhận response từ server (readyState = 4), có thể kiểm tra request thành công hay
không bằng đoạn code.
Ngoài dữ liệu nhận được trong phần body của response bằng 2 thuộc tính responseText
hoặc responseXML, ta có thể truy xuất đến dữ liệu trong phần header của response bằng
Bộ môn HTTT- Khoa CNTT
Hướng dẫn lập trình web bằng ASP.NET
hàm getResponseHeader. Phần thông tin quan trọng nhất trong response header là
Content-Type, phần này cho biết dữ liệu lấy về thuộc loại gì (text, html, image )
Cũng có thể lấy tất cả các thông tin từ response header như sau:
Trong khi thực hiện request, ta cũng có thể thêm các thông tin vào phần header của
request, đây có thể là các thông tin bất kì.
oXmlHttp.setRequestHeader("myheader", "myvalue");
oXmlHttp.send(null);
Bộ môn HTTT- Khoa CNTT
Hướng dẫn lập trình web bằng ASP.NET
Phụ lục
Tham khảo thêm về việc gởi GET request và POST request trong nội dung dưới đây

(trong này có cả phần code của server side)
1. XMLHttp GET Requests
It's time to revisit the hidden frame GET example to see how the process could be improved using
XMLHttp. The first change will be to GetCustomerData.php, which must be changed from an HTML
page to simply return an HTML snippet. The entire file now becomes streamlined:
<?php
header("Content-Type: text/plain");

$sID = $_GET["id"];
$sInfo = "";

$sDBServer = "your.databaser.server";
$sDBName = "your_db_name";
$sDBUsername = "your_db_username";
$sDBPassword = "your_db_password";
$sQuery = "Select * from Customers where CustomerId=".$sID;
$oLink = mysql_connect($sDBServer,$sDBUsername,$sDBPassword);
@mysql_select_db($sDBName) or $sInfo="Unable to open database";

if($oResult = mysql_query($sQuery) and mysql_num_rows($oResult) > 0) {
$aValues = mysql_fetch_array($oResult,MYSQL_ASSOC);
$sInfo = $aValues['Name']."<br />".$aValues['Address']."<br />".
$aValues['City']."<br />".$aValues['State']."<br />".
$aValues['Zip']."<br /><br />Phone: ".$aValues['Phone']."<br />".
"<a href=\"mailto:".$aValues['E-mail']."\">".
$aValues['E-mail']."</a>";
} else {
$sInfo = "Customer with ID $sID doesn't exist.";
}


mysql_close($oLink);
echo $sInfo;
?>
As you can see, there are no visible HTML or JavaScript calls in the page. All the main logic remains
the same, but there are two additional lines of PHP code. The first occurs at the beginning, where the
header() function is used to set the content type of the page. Even though the page will return an
HTML snippet, it's fine to set the content type as text/plain, because it's not a complete HTML page
(and therefore wouldn't validate as HTML). You should always set the content type in any page that is
sending non-HTML to the browser. The second added line is towards the bottom, where the $sInfo
variable is output to the stream by using the echo command.
Bộ môn HTTT- Khoa CNTT
Hướng dẫn lập trình web bằng ASP.NET
In the main HTML page, the basic setup is this:
<p>Enter customer ID number to retrieve information:</p>
<p>Customer ID: <input type="text" id="txtCustomerId" value="" /></p>
<p><input type="button" value="Get Customer Info"
onclick="requestCustomerInfo()" /></p>
<div id="divCustomerInfo"></div>
The requestCustomerInfo() function previously created a hidden iframe but now must
be changed to use XMLHttp:
function requestCustomerInfo() {
var sId = document.getElementById("txtCustomerId").value;
var oXmlHttp = zXmlHttp.createRequest();
oXmlHttp.open("get", "GetCustomerData.php?id=" + sId, true);
oXmlHttp.onreadystatechange = function () {
if (oXmlHttp.readyState == 4) {
if (oXmlHttp.status == 200) {
displayCustomerInfo(oXmlHttp.responseText);
} else {
displayCustomerInfo("An error occurred: " +

oXmlHttp.statusText);
}
}
};
oXmlHttp.send(null);
}
Note that the function begins the same way, by retrieving the ID the user entered. Then, an XMLHttp
object is created using the zXml library. The open() method is called, specifying an asynchronous
GET request for GetCustomerData.php (which has the aforementioned ID added to its query string).
Next comes the assignment of the event handler, which checks for a readyState of 4 and then checks
the status of the request. If the request was successful (status of 200), the displayCustomerInfo()
function is called with the response body (accessed via responseText). If there was an error (status
is not 200), then the error information is passed to displayCustomerInfo().
There are several differences between this and the hidden frame/iframe example. First, no JavaScript
code is required outside of the main page. This is important because any time you need to keep code in
two different places there is the possibility of creating incompatibilities; in the frame-based examples,
you relied on separate scripts in the display page and the hidden frames to communicate with one
another. By changing GetCustomerInfo.php to return just the data you're interested in, you have
eliminated potential problems with JavaScript calling between these locations. The second difference
is that it's much easier to tell if there was a problem executing the request. In previous examples, there
was no mechanism by which you could identify and respond to a server error in the request process.
Using XMLHttp, all server errors are revealed to you as a developer, enabling you to pass along
meaningful error feedback to the user. In many ways, XMLHttp is a more elegant solution than hidden
frames for in-page HTTP requests.
2. XMLHttp POST Requests
Now that you've seen how XMLHttp can simplify GET requests, it's time to take a look at POST
requests. First, you need to make the same changes to SaveCustomer.php as you did for
Bộ môn HTTT- Khoa CNTT
Hướng dẫn lập trình web bằng ASP.NET
GetCustomerInfo.php, which means you need to remove extraneous HTML and JavaScript, add the

content type information, and output the text:
<?php
header("Content-Type: text/plain");
$sName = $_POST["txtName"];
$sAddress = $_POST["txtAddress"];
$sCity = $_POST["txtCity"];
$sState = $_POST["txtState"];
$sZipCode = $_POST["txtZipCode"];
$sPhone = $_POST["txtPhone"];
$sEmail = $_POST["txtEmail"];

$sStatus = "";

$sDBServer = "your.database.server";
$sDBName = "your_db_name";
$sDBUsername = "your_db_username";
$sDBPassword = "your_db_password";
$sSQL = "Insert into Customers
(Name,Address,City,State,Zip,Phone,`E-mail`) ".
" values ('$sName','$sAddress','$sCity','$sState', '$sZipCode'".
", '$sPhone', '$sEmail')";
$oLink = mysql_connect($sDBServer,$sDBUsername,$sDBPassword);
@mysql_select_db($sDBName) or $sStatus = "Unable to open database";

if($oResult = mysql_query($sSQL)) {
$sStatus = "Added customer; customer ID is ".mysql_insert_id();
} else {
$sStatus = "An error occurred
while inserting; customer not saved.";
}


mysql_close($oLink);
echo $sStatus;
?>
This now represents the entirety of SaveCustomer.php. Note that the header() function is called to
set the content type, and echo is used to output $sStatus.
In the main page, the simple form that was set up to allow entry of new customer info is the following:
<form method="post" action="SaveCustomer.php"
onsubmit="sendRequest(); return false">
<p>Enter customer information to be saved:</p>
<p>Customer Name: <input type="text" name="txtName" value="" /><br />
Address: <input type="text" name="txtAddress" value="" /><br />
City: <input type="text" name="txtCity" value="" /><br />
State: <input type="text" name="txtState" value="" /><br />
Bộ môn HTTT- Khoa CNTT
Hướng dẫn lập trình web bằng ASP.NET
Zip Code: <input type="text" name="txtZipCode" value="" /><br />
Phone: <input type="text" name="txtPhone" value="" /><br />
E-mail: <input type="text" name="txtEmail" value="" /></p>
<p><input type="submit" value="Save Customer Info" /></p>
</form>
<div id="divStatus"></div>
You'll note that the onsubmit event handler has now changed to call the function sendRequest()
(although the event handler still returns false to prevent actual form submission). This method first
assembles the data for the POST request and then creates the XMLHttp object to send it. The data must
be sent in the format as a query string:
name1=value1&name2=value2&name3=value3
Both the name and value of each parameter must be URL-encoded in order to avoid data loss during
transmission. JavaScript provides a built-in function called encodeURIComponent() that can be used
to perform this encoding. To create this string, you'll need to iterate over the form fields, extracting and

encoding the name and value. The getRequestBody() function handles this:
function getRequestBody(oForm) {
var aParams = new Array();

for (var i=0 ; i < oForm.elements.length; i++) {
var sParam = encodeURIComponent(oForm.elements[i].name);
sParam += "=";
sParam += encodeURIComponent(oForm.elements[i].value);
aParams.push(sParam);
}

return aParams.join("&");
}
This function assumes that you will supply a reference to the form as an argument. An array (aParams)
is created to store each individual name-value pair. Then, the elements of the form are iterated over,
building up a string and storing it in sParam, which is then added to the array. Doing this prevents
multiple string concatenation, which can lead to slower code execution in some browsers. The last step
is to call join() on the array, passing in the ampersand character. This effectively combines all the
name-value pairs with ampersands, creating a single string in the correct format.
String concatenation in most browsers is an expensive process because strings are immutable, meaning
that once created, they cannot have their values changed. Thus, concatenating two strings involves first
allocating a new string and then copying the contents of the two other strings into it. Repeating this
process over and over causes a severe slowdown. For this reason, it's always best to keep string
concatenations at a minimum and use the array's join() method to handle longer string concatenation.
The sendRequest() function calls getRequestBody() and sets up the request:
function sendRequest() {
var oForm = document.forms[0];
var sBody = getRequestBody(oForm);
var oXmlHttp = zXmlHttp.createRequest();
Bộ môn HTTT- Khoa CNTT

Hướng dẫn lập trình web bằng ASP.NET
oXmlHttp.open("post", oForm.action, true);
oXmlHttp.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");

oXmlHttp.onreadystatechange = function () {
if (oXmlHttp.readyState == 4) {
if (oXmlHttp.status == 200) {
saveResult(oXmlHttp.responseText);
} else {
saveResult("An error occurred: " + oXmlHttp.statusText);
}
}
};
oXmlHttp.send(sBody);
}
As with previous examples, the first step in this function is to get a reference to the form and store it in
a variable (oForm). Then, the request body is generated and stored in sBody. Next comes the creation
and setup of the XMLHttp object. Note that the first argument of open() is now post instead of get,
and the second is set to oForm.action (once again, so this script can be used on multiple pages).
You'll also notice that a request header is being set. When a form is posted from the browser to a
server, it sets the content type of the request as application/x-www-form-urlencoded. Most server-
side languages look for this encoding in order to parse the incoming POST data properly, so it is very
important for it to be set.
The onreadystatechange event handler is very similar to that of the GET example; the only change is
the call to saveResult() instead of displayCustomerInfo(). The last line is very important, as the
sBody string is passed to send() so that it will become part of the request body. This effectively
mimics what the browser does, so all server-side logic should work as expected.
3. Advantages and Disadvantages of XMLHttp
Undoubtedly, you can see the advantage of using XMLHttp for client-server communication instead of

hidden frames. The code you write is much cleaner and the intent of the code is much more apparent
than using numerous callback functions with hidden frames. You have access to request and response
headers as well as HTTP status codes, enabling you to determine if your request was successful.
The downside is that, unlike hidden frames, there is no browser history record of the calls that were
made. The Back and Forward buttons do not tie in to XMLHttp requests, so you have effectively cut
off their use. It is for this reason that many Ajax applications use a mixture of XMLHttp and hidden
frames to make a truly usable interface.
Another disadvantage, which applies to Internet Explorer only, is that you depend on ActiveX controls
being enabled. If the user has your page set up in a particular security zone that doesn't allow ActiveX
controls, you cannot access the XMLHttp object. In that case, you may have to default to using hidden
frames.
Bộ môn HTTT- Khoa CNTT

×