本hack講的是不刷新頁面顯示服務器信息。
用戶可以通過輸入text和服務器組件交互而不用每次都等待頁面的刷新。一個典型的例子就是拼寫檢測或自動完成fIEld[Hack #78]。使用request 對象作為媒介,服務器組件可以和用戶之間實時交互。
本hack顯示一個自動的服務器響應,響應無刷新的顯示在text中。本hack是[Hack #12]的擴展,該hack使用request對象將用戶提交的數據傳送給服務器組件。
本hack獲取用戶提交的信息,並將統計的結果顯示在相同的標簽裡邊。你也可以使用clIEnt-side JavaScript完成相同的工作,當然,為了證明某個服務器組件做了這個工作,本hack還顯示了服務器的一些信息。
圖2-2 顯示了初始頁面
圖2-3顯示了輸入信息以後按tab後的結果
下面是頁面的Html代碼。引入了js文件hacks_2_1.JS。
“http://www.w3.org/TR/2000/REC-xhtml1–20000126/DTD/xHtml1-strict.dtd”>
上一個hack講的是如何無刷新地提交用戶信息。換句話說,在用戶鍵入一些信息並按tab按鈕或點擊其他區域後,text裡邊的數據就被傳送給了服務器。
onblur事件將調用getInfo( )函數,將text中的信息作為參數傳遞。
完整的代碼在hack12裡邊,在這裡就不再完整列舉了。下面將getInfo( )函數和handleResponse( )函數作為重點介紹一下。
function getInfo(obj){
if (obj == null ) { return; }
formObj=obj;
formObjTyp =obj.tagName;
if(formObjTyp "input" || formObjTyp "INPUT"){
formObjTyp = formObjTyp " "formObj.type;
}
formObjTyp = formObjTyp.toLowerCase( );
var url = “http://www.parkerriver.com/s/webforms?objtype=”+
encodeURIComponent(formObjTyp)+“&val=”+
encodeURIComponent(obj.value);
httpRequest(“GET”,url,true);
}
這個函數將用戶鍵入的信息作為val參數傳遞給服務器組件。此外obj參數持有的是text對象,用來取得鍵入的信息。這是一個DOM對象,如HTMLInputElement或HtmlTextAreaElement
即時服務器消息傳遞
服務器程序取得用戶鍵入的信息,然後將統計的結果返回。為了確定響應信息,服務器返回的信息的格式是JSON格式[Hack #7]。JSON是一種很容易處理的XML文件格式。
返回的數據也可以作為一個簡單的字符串。使用JSON格式只是作者的個人愛好而以。不過確實很容易使用。
下面的代碼是一個服務器返回的JSON文件,如果用戶在textarea裡鍵入了55個詞:
{
Form_fIEld_type: “textarea”,
Text_length: “385”,
Word_count: “55”,
Server_inf “apache Tomcat/5.0.19”
}
這段代碼描述了一個有四個不同屬性的JS對象:Form_fIEld_type, Text_length,Word_count, 和Server_info. 下面的代碼也顯示了如何處理這個對象的每個屬性。接著heack取得這一服務器響應信息,並將它插入到textarea裡邊。
handleResponse( )函數:
//event handler for XMLHttpRequest
function handleResponse( ){
try{
if(request.readyState == 4){
if(request.status == 200){
var resp = request.responseText;
if(resp != null){
var func = new Function(“return ”+resp);
var objt = func( );
if(formObjTyp == “textarea”{
if(formObj != null){
formObj.value = objt.Form_fIEld_type +
“ character count: ”+objt.Text_length+
“\\nWord count: ”+
objt.Word_count+“\\nServer inf ”+
objt.Server_info;
}
} else if(formObjTyp == “input text”{
if(formObj != null){
formObj.value = objt.Form_fIEld_type +
“ # characters: ”+objt.Text_length+
“ Word count: ”+objt.Word_count; }
}
}
} else {
//request.status is 503
//if the application isn‘t available;
//500 if the application has a bug
alert(
“A problem occurred with communicating ”+
“between the XMLHttpRequest object and ”+
“the server program.”;
}
}//end outer if
} catch (err) {
alert(err.name);
alert(“It does not appear that the server ”+
“is available for this application. Please”+
“ try again very soon. \\nError: ”+err.message);
}
}
代碼以文本格式取得響應信息。因為文本的格式是JSON(作為js的對象),代碼使用了這一特殊的技術在hack7裡邊。構造函數將text作為一個JS對象返回。在這個例子裡,objt變量指的是服務器組件的響應,使用傳遞對象方法,你可以使用objt.Server_info來取得服務器信息。
下面的代碼就是將響應信息作為一個對象返回:
var resp = request.responseText;
var func = new Function(“return ”+resp);
//call the function and return the object to which
//the objt variable now points
var objt = func( );
下面的代碼是將信息插入到textarea裡邊。
if(formObjTyp == "textarea"){
if(formObj!= null){
formObj.value = objt.Form_fIEld_type +
“ character count: ”+objt.Text_length+
“\\nWord count: ”+
objt.Word_count+“\\nServer inf ”+
objt.Server_info;
}
}
圖2-3顯示了結果。
你可以訪問 textarea,使因為這是一個頂級JavaScript變量,formObj指向了它。代碼的關鍵之一是設置textarea或text的值。
當服務器發信息給textarea而不是text時,會包括換行(\\n in JavaScript),因為textarea能顯示更多文本。而text不能包含換行符,因為text只有一行。