技术开发 频道

详解Ajax中XMLHttp请求及利弊分析

现在,让我们来回顾一下GET示例中的隐藏框架(frame),来看一下使用XMLHttp,是怎样改善处理效率的。第一个目标是GetCustomerDate.php,在对其进行修改后,从一个HTML页变为仅是返回一个HTML代码段,以下是精简过的代码:

<?php header("Content-Type: text/plain"); $sID = $_GET["id"]; $sInfo = ""; $sDBServer = "your.databaser.server"; $sDBName = "your_db_name"; $sDBUsername = "your_db_username"; $sDBPassword = "your_db_password"; $sQuery = "Select * from Customers where CustomerId=".$sID; $oLink = mysql_connect($sDBServer,$sDBUsername,$sDBPassword); @mysql_select_db($sDBName) or $sInfo="不能打开数据库!"; if($oResult = mysql_query($sQuery) and mysql_num_rows($oResult) > 0) { $aValues = mysql_fetch_array($oResult,MYSQL_ASSOC); $sInfo = $aValues['Name']."<br />".$aValues['Address']."<br />". $aValues['City']."<br />".$aValues['State']."<br />". $aValues['Zip']."<br /><br />Phone: ".$aValues['Phone']."<br />". "<a href=\"mailto:".$aValues['E-mail']."\">". $aValues['E-mail']."</a>"; } else{ $sInfo = "ID为$sID的客户不存在!"; } mysql_close($oLink); echo $sInfo; ?>

正如大家所看到的,在页面中没有明显可见的HTML或JavaScript调用,所有的主逻辑保持一致,但加入了两行额外的PHP代码。第一处是在开始处,也就是调用header函数来设置页面的内容类型,即使页面将返回一个HTML代码段,最好也把内容类型设为纯文本(text/plain),因为它不完全是一个HTML页面(因此也不能验证为HTML)。在发送非HTML页面给浏览器时,都应设置好内容类型;第二处是在结尾处,使用echo命令把$sinfo输出到流中。

在主页中——也就是用户访问的第一页,基本设置如下所示:

<p>Enter customer ID number to retrieve information:</p> <p>Customer ID: <input type="text" id="txtCustomerId" value="" /></p> <p><input type="button" value="Get Customer Info" onclick="requestCustomerInfo()" /></p> <div id="divCustomerInfo"></div>

而之前的requestCustomerInfo()函数创建了一个隐藏的iframe,但现在作出修改以使用XMLHttp:

function requestCustomerInfo() { var sId = document.getElementById("txtCustomerId").value; var oXmlHttp = zXmlHttp.createRequest(); oXmlHttp.open("get", "GetCustomerData.php?id=" + sId, true); oXmlHttp.onreadystatechange = function () { if (oXmlHttp.readyState == 4) { if (oXmlHttp.status == 200) { displayCustomerInfo(oXmlHttp.responseText); } else { displayCustomerInfo("错误为:" +oXmlHttp.statusText); } } }; oXmlHttp.send(null); }

请注意,函数以同样的方式开始,即取回用户输入的ID,接着,使用zXml库创建了一个XMLHttp对象,调用open()方法之后,为GetCustomerData.php指定了一个异步的GET请求(其在查询字符串中加入了前述的ID);之后,赋值了一个事件处理函数,除了检查readyState是否为4之外,还要检查请求的status。如果请求成功(status为200),将传递响应体(通过responseText得到)调用displayCustomerInfo()函数;如果有错误发生(status不是200),将会把错误信息传递给displayCustomerInfo()。
在此例和隐藏框架(frame/iframe)示例之间,有几个不同点。首先,在主页之外,不需要JavaScript代码,这点尤其重要,因为当你需要把代码保存在两个不同的地方时,有可能造成兼容性问题,如在基于框架的示例中,是依靠显示页与隐藏框架中各自不同的脚本来相互通讯的,而通过修改GetCustomerInfo.php来返回感兴趣的数据,就已经消除了用JavaScript在两者之间调用的潜在问题。第二个不同之处在于,现在更容易知道,在执行请求期间,是否有问题发生;在前一个例子中,没有在请求处理过程中识别和响应服务器错误的机制,而使用XMLHttp后,所有的服务器错误信息都将展现给作为开发者的你,使你能够只把有意义的错误信息回馈给用户,在大多数时候,对于页内的HTTP请求,XMLHttp都是比隐藏框架更“优雅”的解决方案。


现在,在看过XMLHttp是怎样简化GET请求之后,再来看一下POST请求吧。首先,需要对SaveCustomer.php作出与GetCustomerInfo.php同样的修改,也就是说需要删除无关的HTML与JavaScript代码,加入内容类型信息,并输出相应的文本:

<?php header("Content-Type: text/plain"); $sName = $_POST["txtName"]; $sAddress = $_POST["txtAddress"]; $sCity = $_POST["txtCity"]; $sState = $_POST["txtState"]; $sZipCode = $_POST["txtZipCode"]; $sPhone = $_POST["txtPhone"]; $sEmail = $_POST["txtEmail"]; $sStatus = ""; $sDBServer = "your.database.server"; $sDBName = "your_db_name"; $sDBUsername = "your_db_username"; $sDBPassword = "your_db_password"; $sSQL = "Insert into Customers (Name,Address,City,State,Zip,Phone,`E-mail`) ". " values ('$sName','$sAddress','$sCity','$sState', '$sZipCode'". ", '$sPhone', '$sEmail')"; $oLink = mysql_connect($sDBServer,$sDBUsername,$sDBPassword); @mysql_select_db($sDBName) or $sStatus = "不能打开数据库!"; if($oResult = mysql_query($sSQL)) { $sStatus = "加入的客户;客户ID为".mysql_insert_id(); } else { $sStatus = "在插入操作时有错误发生;客户未保存!"; } mysql_close($oLink); echo $sStatus; ?>
0
相关文章