51.3 Ajax执行流程举例 为了帮助大家更好的了解Ajax在RL-TCPnet中的工作原理,我们这里举一个例子,创建一个如下所示的控制界面。8个复选框用来反馈板子上8个实体按键的状态。“Refresh”按钮用于手动刷新8个复选框的状态,而“Periodic”复选框用于开启周期性更新8个复选框的状态。 使用Ajax需要用户添加官方做好的JavaScript文件xml_http.js(以MDK4.74为例,在MDK安装目录的C:\Keil_v474\ARM\RL\TCPnet\Java文件里面)。XML管理的动态更新数据也要单独创建一个文件。XML文件的后缀名是.cgx,跟CGI脚本文本的后缀cgi要区分开。 首先来看buttons.cgi文件的代码,重点看标签<script></script>之间的JavaScript函数和标签<form></form>之间的输入表单。 - #------------------------------------------------
- # HTML script in buttons.cgi
- #------------------------------------------------
- t <html><head><title>Button inputs</title>
- t <script language=JavaScript type="text/javascript" src="xml_http.js"></script>
- t <script language=JavaScript type="text/javascript">
- # Define URL and refresh timeout
- t var formUpdate = new periodicObj("buttons.cgx", 300);
- t function periodicUpdate() {
- t if(document.getElementById("refreshChkBox").checked == true) {
- t updateMultiple(formUpdate);
- t periodicFormTime = setTimeout("periodicUpdate()", formUpdate.period);
- t }
- t else
- t clearTimeout(periodicFormTime);
- t }
- t </script></head>
- i pg_header.inc
- t <h3 align="center"><br>Buttons on the board</h3>
- t <p><font size="2">This page allows you to monitor on board buttons state.
- t Periodic screen update is based on <b>xml</b> technology. This results in smooth
- t flicker-free screen update.<br><br>
- t Press a button on an evaluation board and observe the change on the screen.</font></p>
- t <form action="buttons.cgi" method="post" id="form1" name="form1">
- t <table border="0" width=99%><font size="3">
- t <tr bgcolor=#aaccff>
- t <th width=40%>Item</th>
- t <th width=60%>Status</th>
- t </tr>
- t <tr>
- t <td><img src="pabb.gif">Buttons [7..0]:</td>
- t <td align="center">
- t <input type="checkbox" disabled id="button7">7
- t <input type="checkbox" disabled id="button6">6
- t <input type="checkbox" disabled id="button5">5
- t <input type="checkbox" disabled id="button4">4
- t <input type="checkbox" disabled id="button3">3
- t <input type="checkbox" disabled id="button2">2
- t <input type="checkbox" disabled id="button1">1
- t <input type="checkbox" disabled id="button0">0
- t </td>
- t </tr>
- t </font></table>
- t <p align="center">
- t <input type="button" id="refreshBtn" value="Refresh" onclick="updateMultiple(formUpdate)">
- t Periodic:<input type="checkbox" id="refreshChkBox" onclick="periodicUpdate()">
- t </p></form>
- i pg_footer.inc
- . End of script must be closed with period.
复制代码从上面的输入表单中可以看出: (1)创建了8个复选框checkbox。 (2)一个刷新按钮button。 (3)还有一个控制周期刷新的复选框checkbox。
51.3.1 点击按钮实现的单次更新过程 当用户在浏览器上按下按钮button时,会触发buttons.cgi文件中设置的按钮触发事件onclick=“updateMultiple(formUpdate)”,从而浏览器会从服务器下载JavaScript函数updateMultiple()并执行,函数updateMultiple是在xml_http.js文件中实现: - /*----------------------------------------
- * xml_http.js
- *---------------------------------------*/
- function updateMultiple(formUpd, callBack, userName, userPassword) {
- xmlHttp = GetXmlHttpObject();
- if(xmlHttp == null) {
- alert("XmlHttp not initialized!");
- return 0;
- }
- xmlHttp.onreadystatechange = responseHandler;
- xmlHttp.open("GET", formUpd.url, true, userName, userPassword);
- xmlHttp.send(null);
-
- function responseHandler(){
- if(xmlHttp.readyState == 4) { //response ready
- if(xmlHttp.status == 200) { //handle received data
- var xmlDoc = xmlHttp.responseXML;
- if(xmlDoc == null)
- return 0;
- try { //catching IE bug
- processResponse(xmlDoc);
- }
- catch(e) {
- return 0;
- }
- /* Callback function for custom update. */
- if (callBack != undefined)
- callBack();
- }
- else if(xmlHttp.status == 401)
- alert("Error code 401: Unauthorized");
- else if(xmlHttp.status == 403)
- alert("Error code 403: Forbidden");
- else if(xmlHttp.status == 404)
- alert("Error code 404: URL not found!");
- }
- }
- }
复制代码函数updateMultiple的形参是formUpdate,这个是在buttons.cgi文件中创建的JavaScript对象: - #--------------------------------------
- # buttons.cgi
- #--------------------------------------
- t var formUpdate = new periodicObj ("buttons.cgx", 300);
复制代码而函数periodicObj也是在xml_http.js中实现,定义了周期性更新的文件,时间单位ms。这里是浏览器300ms后下载一次buttons.cgx文件进行更新。 - /* Objects templates */
- function periodicObj(url, period) {
- this.url = url;
- this.period = (typeof period == "undefined") ? 0 : period;
- }
复制代码buttons.cgx文件的实现如下。 - #--------------------------------------
- # Buttons.cgx
- #--------------------------------------
- t <form>
- c y0
- c y1
- c y2
- c y3
- c y4
- c y5
- c y6
- c y7
- t </form>
复制代码对于XML文件来说,仅写入要更新的元素即可,并以标签<form>开始,标签</form>结束。这个XML文件里面也有CGI脚本命令,会触发HTTP_CGI.c文件中的脚本解析函数cgi_func的执行: - /*---------------------------------------
- * cgi_func() in HTTP_CGI.c
- *--------------------------------------*/
- case 'y':
- len = sprintf (
- (char*) buf,
- "<checkbox><id><button%c</id> <on>%s</on></checkbox>",
- env [1],
- (get_button () & (1<<(env [1]-'0'))) ? "true" : "false"
- );
- break;
复制代码几条脚本命令全部解析后,就会返回8个checkbox的状态给浏览器,即buttons.cgx文件中的代码会全部传给浏览器进行更新。 - <!-----------------------------------------
- # Generated XML
- #----------------------------------------->
- <form>
- <checkbox><id>button0</id><on>true</on></checkbox>
- <checkbox><id>button1</id><on>false</on></checkbox>
- <checkbox><id>button2</id><on>false</on></checkbox>
- <checkbox><id>button3</id><on>false</on></checkbox>
- <checkbox><id>button4</id><on>false</on></checkbox>
- <checkbox><id>button5</id><on>false</on></checkbox>
- <checkbox><id>button6</id><on>false</on></checkbox>
- <checkbox><id>button7</id><on>false</on></checkbox>
- </form>
复制代码特别注意: 1、XML文件buttons.cgx中的每行语句不可超过120个字符。 2、函数cgi_func返回的XML代码中不能有空格和回车换行符。 3、XML文件的后缀务必要是cgx,防止WebServer的脚本解析器无法正确识别。
51.3.2 选中复选框后的周期性更新过程 如果用户选中了定期更新复选框,浏览器将调用函数periodicUpdate()并执行。 - #--------------------------------------
- # buttons.cgi
- #--------------------------------------
- t function periodicUpdate() {
- t if (document.getElementById ("refreshChkBox").checked == true) {
- t updateMultiple (formUpdate);
- t periodicFormTime = setTimeout ("periodicUpdate ()",formUpdate.period);
- t } else {
- t clearTimeout (periodicFormTime);
- t }
- t }
复制代码
1、这个JavaScript函数在buttons.cgi文件中的<head>标签里面,主要功能是通过判断复选框是否选中了,如果选中了,将调用函数updateMultiple,更新8个复选框的状态并返回给浏览器。并通过函数setTimeout启动了一个单次定时器,设置时间为formUpdate.period,单位毫秒。时间到后会再次调用函数periodicUpdate,从而实现了周期更新的效果。 2、如果复选框取消选中或者未选中,调用函数clearTimeout停止开启的单次定时器。
至此,通过Ajax就实现了网页的局部刷新,实际效果极佳。
|