[AJAX] Lesson 3 - 使用JS即時更新版面

簡介

接著這篇就要來解說JS如何去把XML傳回的資料去做版面的即時更新。我們再稍微複習一下,從[AJAX] Lesson 1 - AJAX介紹與XML的基本架構 文章中所畫的流程圖,前一篇文章已經利用PHP來建立XML,而這個XML負責的就是哪些資料需要傳給Server後,再取回給使用端電腦去作版面的即時更新或其他處理,因此本篇算是蠻核心的整理,JS所有的處理將會一一的解說。


內文

在撰寫XML內文時,我們已經告知要傳給Server的資料名稱為”food”,而這個”food”資料會在Server端去與資料庫(foodArray)比對,查看是否有相同值的資料,再依據不同的情形給予不同的回應,整個流程簡單明瞭。
那麼,我們就先來看如何用JS來對Server端發出連繫請求,程式碼如下:

var xmlHttp = createXmlHttpRequestObject();  

function createXmlHttpRequestObject(){
var xmlHttp;

if(window.ActiveXObject){ 
    try{
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }catch(e){
        xmlHttp = false;
    }
}else{ 
    try{
        xmlHttp = new XMLHttpRequest();
    }catch(e){
        xmlHttp = false;
    }
}

if(!xmlHttp)
    alert("Cant create that object !")
else
    return xmlHttp;
}

createXmlHttpRequestObject這個函式主要就是在向Server發出連繫請求,而這個請求在先進的瀏覽器是由XMLHttpRequest()來負責,而版本較舊的瀏覽器則是用ActiveXObject(“Microsoft.XMLHTTP”)此函式來負責。聯繫請求完成之後,就要來撰寫哪些資料是要傳給Server了,程式碼如下:

function process(){
if(xmlHttp.readyState==0 || xmlHttp.readyState==4){
    food = encodeURIComponent(document.getElementById("userInput").value);
    xmlHttp.open("GET", "foodstore.php?food="+food,true);
    xmlHttp.onreadystatechange = handleServerResponse;
    xmlHttp.send(null);
}else{
    setTimeout('process()',1000);
}
}

XMLHttpRequest.readyState屬性是回傳請求準備狀態,狀態代碼分別是0~4,其各別意思我從MDN網站上截取說明會比較清楚且快速點,如下。




UNSENT:
The XMLHttpRequest client has been created, but the open() method hasn’t been called yet.
OPENED:
open() method has been invoked. During this state, the request headers can be set using the setRequestHeader() method and the send() method can be called which will initiate the fetch.
HEADERS_RECEIVED:
send() has been called and the response headers have been received.
LOADING:
Response’s body is being received. If responseType is “text” or empty string, responseText will have the partial text response as it loads.
DONE:
The fetch operation is complete. This could mean that either the data transfer has been completed successfully or failed.

而xmlHttp.open()函式是初始化請求,其參數分別是(method, url, async),method是傳值給Server的方式,分別是”GET”、”POST”,相信有學過HTML和PHP的同學應該都不陌生。URL是我們要傳值的對象,這裡的對象當然就是我們建立的XML,因為它要與資料庫比對,並且JS要向它取回回應。

xmlHttp.onreadystatechange是一個事件處理器(event handler),當呼叫.open()之後,readyState會有所變化,這時就要處理向XML取回回應,.onreadystatechange就是為此而生,這裡我們將handleServerResponse函式(後面會說明)指派給它,因此後面不需要加”()”,這裡在網路上也是很多人討論的點。

xmlHttp.send()是將請求傳送給Server,這裡我們.open()的方法是”GET”,因此.send()參數為”nul”,其原因我之後會再整理一篇文章。若條件不成立,則1秒後再進行一次process()函式。

接著就是handleServerResponse()函式的內容了,程式碼如下:

function handleServerResponse(){
if(xmlHttp.readyState==4 && xmlHttp.status==200){ 
        xmlResponse = xmlHttp.responseXML;
        xmlDocumentElement = xmlResponse.documentElement;
        message = xmlDocumentElement.firstChild.data;
        document.getElementById("underInput").innerHTML = message;
        setTimeout('process()', 1000);
    }else{
        alert('Someting went wrong !');
    }
}

一樣XMLHttpRequest.status的代碼含意我截取StackOverflow網站上的大大討論的答覆,如下:

500 - 599: the server had an error
400 - 499: this is a client error (Ex: 404 page not found)
300 - 399: then exists a redirect
200 - 299: then it is correct and
100 - 199: means information message

我們將XML取回的回應指派給xmlResponse變數,再來就是一個重點了,XML是一個樹狀的資料結構,意思就是每個元素存在著父子關係,舉例來說HTML裡的body、head這些都是屬於html的子結點,相對的html就是它們的父節點,同樣的原理,若我們在body放元素,這些元素也都屬於body的子節點。

再回來看看我們建立XML,response標籤就是.responseXML取回的內容,xmlDocumentElement = xmlResponse.documentElement;即是取得XML的response標籤內的元素,而它的第一個子節點便是”echo”,即依據XML比對資料庫結果給與的回應,再將此回應指派給ID為underInput的元素來顯示。

點我看最終結果

參考

  1. Bucky Roberts的Youtube教學影片
  2. MDN
  3. StackOverflow

留言