Dedian |
|
|||
-- 關(guān)注搜索引擎的開發(fā) |
日歷
統(tǒng)計(jì)
導(dǎo)航常用鏈接留言簿(8)隨筆分類(45)
隨筆檔案(82)
文章檔案(2)Java Spaces搜索積分與排名
最新評(píng)論
閱讀排行榜評(píng)論排行榜 |
---祝大家中秋愉快--- Ajax (AsynchronousJavaScript and XML)是近年來流行的一門web 技術(shù)。在Blogjava上看到有人開始在介紹AJAX,但仿佛流于概念或理論的東西,對于想用Ajax的初學(xué)者似乎不是很make sense。我想,學(xué)習(xí)任何一樣新的技術(shù),例子和步驟是極為make sense的兩樣?xùn)|西。 筆者想結(jié)合過去的學(xué)習(xí)經(jīng)驗(yàn)簡單講講使用Ajax的基本步驟和舉幾個(gè)實(shí)用例子。由于筆者主要在于后臺(tái)端的開發(fā),所以很多腳本并不是很擅長。Ajax也主要限于以前大學(xué)的修課和近期的一些為后臺(tái)端程序的測試的簡單實(shí)現(xiàn)。所以只是一個(gè)拋磚引玉的使用Ajax版本,歡迎相互學(xué)習(xí)交流。 0. 導(dǎo)讀 ??? 1。使用Ajax的基本流程 ??? 2。使用Ajax的基本步驟。(簡單例子--> Demo) ??? 3。再來一個(gè)例子(Google Suggest)。(Demo) ??? 4。家庭作業(yè) :) 1。使用Ajax的基本流程 在筆者看來,Ajax更像是一個(gè)簡單的網(wǎng)絡(luò)框架,它描述著如何高效地使網(wǎng)絡(luò)前端的數(shù)據(jù)展現(xiàn)和網(wǎng)絡(luò)后端的數(shù)據(jù)之間的交互?;旧?,就是瀏覽器提供一個(gè)XMLHttpRequest(當(dāng)然在IE里是ActiveXObject)的對象向后臺(tái)端的腳本程序或者Servlet Classes發(fā)送http請求,從后臺(tái)端的回應(yīng)中獲取文本數(shù)據(jù)(如xml格式和最近有人討論的Json格式)并嵌入前臺(tái)段的網(wǎng)頁中或腳本中。 下圖是一個(gè)簡單的流程圖: ![]() 2。使用Ajax的基本步驟。 下面,我們結(jié)合上面的流程,以及一個(gè)簡單的例子(見這篇文章)過一遍基本的步驟。(藍(lán)色代碼為標(biāo)準(zhǔn)寫法) 第一步:Form 代碼:接受前臺(tái)端的輸入,并通過Action方法(方法函數(shù)里包含創(chuàng)建XMLHttpRequest對象)把request post到后臺(tái)端。 <input id="username" name="username" type="text" ? onblur="checkName(this.value,'')" /> <span class="hidden" id="nameCheckFailed"> ? This name is in use, please try another. </span> <script language="javascript"> function checkName(input, response) { ? if (response != ''){ ??? // Response mode ??? message?? = document.getElementById('nameCheckFailed'); ??? if (response == '1'){ ????? message.className = 'error'; ??? }else{ ????? message.className = 'hidden'; ??? } ? }else{ ??? // Input mode ??? url? = 'http://localhost/xml/checkUserName.php?q=' + input; ??? loadXMLDoc(url); ? } } var req; function loadXMLDoc(url) { ??? // branch for native XMLHttpRequest object ??? if (window.XMLHttpRequest) { ??????? req = new XMLHttpRequest(); ??????? req.onreadystatechange = processReqChange; ??????? req.open("GET", url, true); ??????? req.send(null); ??? // branch for IE/Windows ActiveX version ??? } else if (window.ActiveXObject) { ??????? req = new ActiveXObject("Microsoft.XMLHTTP"); ??????? if (req) { ??????????? req.onreadystatechange = processReqChange; ??????????? req.open("GET", url, true); ??????????? req.send(); ??????? } ??? } } </script> 注: 1。 這里的form只是一個(gè)input box,action的方法是onblur,就是響應(yīng)失去焦點(diǎn)的事件,然后調(diào)用一個(gè)函數(shù)checkName, 這個(gè)函數(shù)里通過XMLHttpRequest向PHP server script 發(fā)送Post請求(看得出來,這里的php server script的文件名叫checkUserName.php,唯一參數(shù)是q)。 2。函數(shù)loadXMLDoc里有個(gè)通用的創(chuàng)建XMLHttpRequest對象的代碼,標(biāo)準(zhǔn)代碼整理如下: ??????? var req; ??? ??? function foo() ??? ??? { ??? ??? ??? req = false; ??? ??? ??? // branch for native XMLHttpRequest object ??? ??? ??? if(window.XMLHttpRequest) ??? ??? ??? { ??? ??? ??? ??? try ??? ??? ??? ??? { ??? ??? ??? ??? ??? req = new XMLHttpRequest(); ??? ??? ??? ??? } ??? ??? ??? ??? catch(e) ??? ??? ??? ??? { ??? ??? ??? ??? ??? req = false; ??? ??? ??? ??? } ??? ??? ??? } ??? ??? ??? else if(window.ActiveXObject) // branch for IE/Windows ActiveX version ??? ??? ??? { ??? ??? ??? ??? try ??? ??? ??? ??? { ??? ??? ??? ??? ??? req = new ActiveXObject("Msxml2.XMLHTTP"); ??? ??? ??? ??? } ??? ??? ??? ??? catch(e) ??? ??? ??? ??? { ??? ??? ??? ??? ??? try ??? ??? ??? ??? ??? { ??? ??? ??? ??? ??? ??? req = new ActiveXObject("Microsoft.XMLHTTP"); ??? ??? ??? ??? ??? } ??? ??? ??? ??? ??? catch(e) ??? ??? ??? ??? ??? { ??? ??? ??? ??? ??? ??? req = false; ??? ??? ??? ??? ??? } ??? ??? ??? ??? } ??? ??? ??? } ??? ??? ??? if(req) ??? ??? ??? { ??? ?? ?? ?? ?? ??//do something here ???? ??? ??? } ??? ??? ??? ??? ??? } 第二步:響應(yīng)文本處理代碼:XMLHttpRequest對象里有個(gè)類似消息響應(yīng)函數(shù)的屬性,即通過設(shè)置 req.onreadystatechange 來告訴XMLHttpRequest在哪個(gè)函數(shù)里處理服務(wù)端返回的文本信息。 如在上面的例子中:
那么我們接著要有一個(gè)processReqChange的函數(shù): 注:1。 基本上 processReqChange 函數(shù)是標(biāo)準(zhǔn)代碼的寫法。2。這里要用到前面定義的全局變量(XMLHttpRequest對象)req 第三步:后臺(tái)端代碼(這個(gè)例子是php server script):接受前臺(tái)端的請求,處理其參數(shù),并返回相應(yīng)的結(jié)果。 文件名: checkUserName.php <?php header('Content-Type: text/xml'); function nameInUse($q) {? ? if (isset($q)){ ??? switch(strtolower($q)) ??? { ????? case? 'drew' : ????????? return '1'; ????????? break; ????? case? 'fred' : ????????? return '1'; ????????? break; ????? default: ????????? return '0'; ??? } ? }else{ ??? return '0'; ? } ? } ?> <?php echo '<?xml version="1.0" encoding="UTF-8"? standalone="yes"?>'; ?> <response> ? <method>checkName</method> ? <result><?php ??? echo nameInUse($_GET['q']) ?> ? </result> </response> 注:代碼很簡單,就不用解釋了。這里返回的是xml格式的字符串。 總體效果見這里 輸入"fred"或者"drew"的名字,失去焦點(diǎn)后會(huì)顯示名字已存在的信息。 ?3。再來一個(gè)例子。 這里再講一個(gè)實(shí)用的例子,這是以前上課的一個(gè)課堂作業(yè),也很有代表性。是關(guān)于Google Suggest(好像新的Google Toolbar上就用的這個(gè)功能)的應(yīng)用問題。這里是寫好的DEMO。現(xiàn)在越來越多的網(wǎng)站提供類似Web Service的API, 我們利用他們提供的API URL可以返回一些我們用的著的數(shù)據(jù),放在我們的網(wǎng)頁上。這里就用的上Ajax。只不過有些返回來的文本數(shù)據(jù)是xml格式的,就可以利用上面的簡單例子來處理,但很多像Google Suggest那樣是返回一段類似代碼格式的文本。我們就要利用Javascript的eval函數(shù),把這些文本當(dāng)作一段代碼在嵌入自己的網(wǎng)頁中。如果嵌入的代碼中含有函數(shù),則需要自己再寫一個(gè)同名的函數(shù)作為實(shí)現(xiàn)。(這就是流程圖中的optional的func 3) 這里完整代碼就不貼了,貼一些關(guān)鍵代碼(原本后臺(tái)端是用Java Servlet寫的,但做demo的空間沒有Tomcat不支持Servlet,所以改用Php實(shí)現(xiàn),大家可以自己用Java再寫一邊作為家庭作業(yè) :) ): 1) form 代碼: <form name = "QForm" method="POST" action="google_suggest.php"> ??? <table bgcolor="8080C0" width="90%" > ??? <tr> ??? ??? <td? nowrap>Search Term:</td> ??? ??? <td ><input type="text" name="qtext"? onkeyup="return GetSuggestion()" size="60"></td> ??? </tr> ??? <tr> ??? ??? <th colspan="2" align="left" bgcolor="#A8A8FF"><DIV id=google_suggest_target>results go here . . . </DIV></th> ??? </tr> ??? </table> ??? </form> 注: a. 看得出來,要把查詢的字符串post到google_suggest.php上 b. action的函數(shù)是GetSuggestion(),其返回的字符串會(huì)顯示在預(yù)留的網(wǎng)頁空間里。 2) 后臺(tái)端代碼(PHP):這里主要接收前臺(tái)的請求,并不請求轉(zhuǎn)化為向Google Suggest的API URL請求,把接收到的文本信息返回給前端。代碼很簡單,如下: 文件名:google_suggest.php <?php function getGoogleSuggest($q) { ??? $url = "http://www.google.com/complete/search?hl=en&js=true&qu=" . $q; ??? return file_get_contents($url); } ?> <?php echo getGoogleSuggest($_POST['q']) ?> 注: a。 Google Suggest API 返回的是一個(gè)代碼格式的文本信息,如下: sendRPCDone(frameElement, "", new Array(), new Array(), new Array("")); 所以我們再前臺(tái)接受到這個(gè)文本信息之后,應(yīng)該寫一個(gè)sendRPCDone的函數(shù)來做進(jìn)一步信息處理(比如說列表出查詢結(jié)果)。 3) 前臺(tái)文本處理代碼: ??? <script type="text/javascript"> ??? ??? var req; ??? ??? function GetSuggestion() ??? ??? { ??? ??? ??? req = false; ??? ??? ??? var f = document.QForm; ??? ??? ??? // branch for native XMLHttpRequest object ??? ??? ??? if(window.XMLHttpRequest) ??? ??? ??? { ??? ??? ??? ??? try ??? ??? ??? ??? { ??? ??? ??? ??? ??? req = new XMLHttpRequest(); ??? ??? ??? ??? } ??? ??? ??? ??? catch(e) ??? ??? ??? ??? { ??? ??? ??? ??? ??? req = false; ??? ??? ??? ??? } ??? ??? ??? } ??? ??? ??? else if(window.ActiveXObject) // branch for IE/Windows ActiveX version ??? ??? ??? { ??? ??? ??? ??? try ??? ??? ??? ??? { ??? ??? ??? ??? ??? req = new ActiveXObject("Msxml2.XMLHTTP"); ??? ??? ??? ??? } ??? ??? ??? ??? catch(e) ??? ??? ??? ??? { ??? ??? ??? ??? ??? try ??? ??? ??? ??? ??? { ??? ??? ??? ??? ??? ??? req = new ActiveXObject("Microsoft.XMLHTTP"); ??? ??? ??? ??? ??? } ??? ??? ??? ??? ??? catch(e) ??? ??? ??? ??? ??? { ??? ??? ??? ??? ??? ??? req = false; ??? ??? ??? ??? ??? } ??? ??? ??? ??? } ??? ??? ??? } ??? ??? ??? if(req) ??? ??? ??? { ??? ??? ??? ??? var url = "google_suggest.php"; ??????? ??? ??? ??? ??? req.onreadystatechange = processReqChange; ??? ??? ??? ??? req.open("POST", url, true); ??????? ??? ??? req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); ??? ??? ??? ??? req.setRequestHeader("Method", "POST " + url + " HTTP/1.1"); ??? ??? ??? ??? req.send("q=" + escape(document.QForm.qtext.value)); ??? ??? ??? } ??? ??? ??? ??? ??? } ??? ??? ??? ??? function processReqChange() ??? ??? { ??? ??? ??? if(req.readyState == 4) // only if req shows "loaded" ??? ??? ??? { ??? ??? ???????????????? if (req.status == 200) // only if "OK" ??? ??? ???????????????? { ??? ??? ???????????????? ??? ??? x = req.responseText; ??? ??? ???????????????????????? eval(x); ??? ??? ???????????????? } ??? ??? ???????????????? else ??? ??? ???????????????? { ??? ??? ?????????? ??? ??? ????? alert("There was a problem retrieving the XML data:\n" + req.statusText); ??? ??? ???????????????? } ??? ??? ??? } ??? ??? ??? else if(req.readyState == 2) ??? ??? ??? { ??? ??? ??? } ??? ??? } ??? ??? ??? ??? function sendRPCDone(frameElement, qString, arr1, arr2, arr3) ??? ??? { ??? ??? ??? ??? ??? var suggest_results = eval(arr1); ??? ??? ??? var counts = eval(arr2); ??? ??? ??? var htmlstr = "<TABLE cellspacing=4 border=0>"; ??? ??? ??? for (var i=0; i < suggest_results.length; i++) ??? ??? ??? { ??? ??? ??? ??? htmlstr += "<tr><td><a href=\"javascript:self.location=\'http://www.google.com/search?hl=en&q=" + suggest_results[i] + "&btnG=Google+Search\'\">" + suggest_results[i] + "</a></td>"; ??? ??? ??? ??? htmlstr += "<TD width=200><font color= 228b22>" + counts[i] + "</font></TD></TR>" ??? ??? ?????? ??? ? ??? ??? ??? } ??? ??? ??? htmlstr += "</TABLE>"; ??? ??? ??? document.getElementById("google_suggest_target").innerHTML = htmlstr; ??? ??? ??? ??? } ??? ??? ??? ??? </script> 4。家庭作業(yè) :) 一定要自己寫一些代碼,才能鞏固知識(shí):) 題目: 我們經(jīng)常用del.icio.us來收藏我們喜歡的網(wǎng)站或者文章,并加一些類似讀書筆記的注釋。那么我們怎么利用del.icio.us提供的API來訪問我們的讀書筆記信息,并顯示在自己的Blog里呢? 提示: 1。你要有一個(gè)del.icio.us的賬號(hào),并且已經(jīng)有所網(wǎng)頁收藏作為實(shí)驗(yàn)數(shù)據(jù):) 2。API URL 是 "http://del.icio.us/feeds/json/" + "你的賬號(hào)名";自己參看一下,看返回什么樣的格式文本。另外,如果要限制返回的記錄數(shù),可以加"?count=10"這樣的參數(shù)。 最后,祝大家中秋愉快! ---------------------------完----------------------------
評(píng)論:
|
![]() |
|
Copyright © Dedian | Powered by: 博客園 模板提供:滬江博客 |