- UID
- 64909
- 帖子
- 919
- 主題
- 879
- 精華
- 0
- 積分
- 1238
- 楓幣
- 69
- 威望
- 1236
- 存款
- 0
- 贊助金額
- 0
- 推廣
- 0
- GP
- 0
- 閱讀權限
- 70
- 性別
- 保密
- 在線時間
- 48 小時
- 註冊時間
- 2014-6-8
- 最後登入
- 2022-7-11
|
AJAX 為何物?
Ajax 立基於非同步 JavaScript 和 XML。簡單地說,Ajax 即運用非標準的 XMLHttpRequest 物件,並配合伺服器端的 Script 進行通訊。Ajax 能夠傳送並接收各種格式的資訊,其中包括 XML、HTML 和 text 檔案。Ajax 最吸引人之處在於它的〝非同步〞性質,這意味著 Ajax 能做各種動作,而無須更新整個頁面。如此便能透過使用者的事件更新頁面的一小部分。
有兩項即將討論到的特點如下︰
無須重新載入整個頁面,便能對伺服器發送請求
分析並運用 XML 文件
第一步 – 如何發出 HTTP 請求
為了使用 JavaScript 向伺服器發送 HTTP 請求,便需要一個能夠提供相關功能的類別實體(an instance of a class)。這樣的類別最初由 Internet Explorer 以 ActiveX 物件的方式引入,稱為 XMLHTTP。Mozilla、Safari 及其他瀏覽器則隨後跟進,實作了 XMLHttpRequest 類別,以提供微軟最初的 ActiveX 物件中的方法及屬性。
因此,為了建立能夠跨瀏覽器的物件實體,可以這麼寫:
var httpRequest;
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
(出於解說上的需要,上述代碼使用最簡方式建立 XMLHTTP 的實體。較貼近實際運用的範例,見第三步。)
部分版本的 Mozilla 瀏覽器,在伺服器送回的資料未含 XML mime-type 檔頭(header)時會出錯。為了避免這個問題,你可以用下列方法覆寫伺服器傳回的檔頭,以免傳回的不是 text/xml。
httpRequest = new XMLHttpRequest();
httpRequest.overrideMimeType('text/xml');
接下來是要決定伺服器傳回資料後的處理方式,此時你只要以 onreadystatechange 這個屬性指明要處理傳回值的 JavaScript 函式名稱即可,例如:
httpRequest.onreadystatechange = nameOfTheFunction;
注意,指定的函式名稱後不加括號也沒有參數。這只是簡單的賦值,而非真的呼叫函數。除了指定函式名稱外,你也能用 Javascript 即時定義函式的技巧(稱為〝匿名函數〞)來定一個新的處理函式,如下:
httpRequest.onreadystatechange = function(){
// 做些事
};
決定處理方式之後你得確實發出 request,此時需叫用 HTTP request 類別的 open() 及 send() 方法,如下:
httpRequest.open('GET', 'http://www.example.org/some.file', true);
httpRequest.send(null);
open() 的第一個參數是 HTTP request 的方法,也就是從 GET、POST、HEAD 等伺服器支援的方法中擇一使用。為遵循 HTTP 標準,請記得這些方法都是大寫,否則有的瀏覽器(如 Firefox)不會處理這些請求。其他可用的 HTTP request 方法的列表請參考 W3C 規格書。
第二個參數是請求頁面的 URL。基於安全考量,你不能叫用同網域以外的網頁。如果網域不同,則叫用 open() 時會出現「權限不足,拒絕存取」那類的錯誤。常見的錯誤多為在 domain.tld 的網站下呼叫 www.domain.tld 中的網頁,僅是一點點差別都不行。
第三個參數決定此 request 是否不同步進行,如果設定為 TRUE 則即使伺服器尚未傳回資料也會繼續執行其餘的程式,這也就是 AJAX 中第一個 A 代表的意義。
send() 的參數在以 POST 發出 request 時,可以是任何想傳給伺服器的東西,而資料則以查詢字串的方式列出,例如:
name=value&anothername=othervalue&so=on
不過如果你想要以 POST 方式傳送資料,則必須先將 MIME 型態改好,如下:
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
否則伺服器就不會理你傳過來的資料了。
第二步 – 處理伺服器傳回的資料
傳出 request 時必須提供處理傳回值的函數名稱,這個函數是用來處理伺服器的回應。
httpRequest.onreadystatechange = nameOfTheFunction;
那麼來看看這個函數該做些什麼。首先,它必須檢查 request 目前的狀態。如果狀態值為 4 代表伺服器已經傳回所有資訊了,便可以開始解析所得資訊。
if (httpRequest.readyState == 4) {
// 一切 ok, 繼續解析
} else {
// 還沒完成
}
readyState 所有可能的值如下:
0 (還沒開始)
1 (讀取中)
2 (已讀取)
3 (資訊交換中)
4 (一切完成)
(資料來源: MSDN)
接下來要檢查伺服器傳回的 HTTP 狀態碼。所有狀態碼列表可於 W3C 網站上查到,但我們要管的是 200 OK 這種狀態。
if (httpRequest.status == 200) {
// 萬事具備
} else {
// 似乎有點問題,或許伺服器傳回了 404 (查無此頁) 或者 500 (內部錯誤) 什麼的
}
檢查傳回的 HTTP 狀態碼後,要怎麼處理傳回的資料就由你決定了。有兩種存取資料的方式:
httpRequest.responseText – 這樣會把傳回值視為字串用
httpRequest.responseXML – 這樣會把傳回值視為 XMLDocument 物件,而後可用 JavaScript DOM 相關函式處理
第三步 – 簡單範例
好,接著就做一次簡單的 HTTP 範例,演示方才的各項技巧。這段 JavaScript 會向伺服器要一份裡頭有「I'm a test.」字樣的 HTML 文件(test.html),而後以 alert() 將文件內容列出。
<script type="text/javascript" language="javascript">
function makeRequest(url) {
var httpRequest;
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
httpRequest = new XMLHttpRequest();
if (httpRequest.overrideMimeType) {
httpRequest.overrideMimeType('text/xml');
}
}
else if (window.ActiveXObject) { // IE
try {
httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {}
}
}
if (!httpRequest) {
alert('Giving up Cannot create an XMLHTTP instance');
return false;
}
httpRequest.onreadystatechange = function() { alertContents(httpRequest); };
httpRequest.open('GET', url, true);
httpRequest.send('');
}
function alertContents(httpRequest) {
if (httpRequest.readyState == 4) {
if (httpRequest.status == 200) {
alert(httpRequest.responseText);
} else {
alert('There was a problem with the request.');
}
}
}
</script>
<span
style="cursor: pointer; text-decoration: underline"
>
Make a request
</span>
在此範例中:
首先使用者按下「Make a request」
這麼一來就會呼叫 makeRequest() 函式,亦傳入參數值 test.html (也就是那份 HTML 檔的名稱,放在同目錄下)
接著發出 request,而後會將主導權交給 onreadystatechange 指定的 alertContents() 函式
alertContents() 檢查回應是否正常,而後以 alert() 將 test.html 的內容列出
你可以由此測試本例,也可以參考測試檔案。
第四步 – 運用 XML 資料
前面的例子中,在收到 HTTP 傳回值後我們以物件的 reponseText 屬性接收 test.html 檔案的內容,接著來試試 responseXML 屬性。
首先,我們得做個格式正確的 XML 文件以便稍後取用。文件 (test.xml) 內容如下:
<?ban=l version="1.0" ?>
<root>
I'm a test.
</root>
在程式中,我們叫用檔案的地方只須略事修改如下:
...
onclick="makeRequest('test.xml')">
...
接著在 alertContents() 中,我們把 alert(http_request.responseText); 改成這樣:
var xmldoc = httpRequest.responseXML;
var root_node = xmldoc.getElementsByTagName('root').item(0);
alert(root_node.firstChild.data);
|
|