
| CREATE TABLE `Customers` ( `CustomerId` int(11) NOT NULL auto_increment, `Name` varchar(255) NOT NULL default '', `Address` varchar(255) NOT NULL default '', `City` varchar(255) NOT NULL default '', `State` varchar(255) NOT NULL default '', `Zip` varchar(255) NOT NULL default '', `Phone` varchar(255) NOT NULL default '', `E-mail` varchar(255) NOT NULL default '', PRIMARY KEY (`CustomerId`) ) TYPE=MyISAM COMMENT='Sample Customer Data'; |
| <frameset rows="100%,0" frameborder="0"> <frame name="displayFrame" src="display.htm" noresize="noresize" /> <frame name="hiddenFrame" src="about:blank" noresize="noresize" /> </frameset> |
| <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> |
| function requestCustomerInfo() { var sId = document.getElementById("txtCustomerId").value; top.frames["hiddenFrame"].location = "getcustomerdata.php?id=" + sId; } |
| function displayCustomerInfo(sText) { var divCustomerInfo = document.getElementById("divCustomerInfo"); divCustomerInfo.innerHTML = sText; } |
| <html> <head> <title>Get Customer Data</title> <?php //php代码 ?> </head> <body> <div id="divInfoToReturn"><?php echo $sInfo ?></div> </body> </html> |
| window.onload = function () { var divInfoToReturn = document.getElementById("divInfoToReturn"); top.frames["displayFrame"].displayCustomerInfo(divInfoToReturn.innerHTML); }; |
| <?php $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; //更多代码 ?> |
| <?php $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="Unable to open database"; 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 = "Customer with ID $sID doesn't exist."; } mysql_close($oLink); ?> |
突出显示的头两行代码用来完成从PHP到MySQL数据库的连接。紧接着,调用mysql_ query()函数来执行SQL查询。如果函数返回结果,并且该结果至少包括一行,那么程序将获取该信息,并将其存入变量$sInfo中;否则,$sInfo将填入一个错误消息。最后两行则负责释放数据库连接。
关于更复杂的PHP和MySQL编程的阐述已超出了本文讨论的范围。
现在当$sInfo输出到<div/>元素时,它将包含正确的信息。onload事件处理函数将读取这些数据,然后将其发送到显示帧上。如果查询到客户,其相应的信息将会显示出来,如图2-2所示。
另一方面,如果客户不存在,则会在屏幕的相同位置显示错误消息。无论如何,客户服务代表都将获得一个很好的用户体验。你的第一个Ajax程序也就完成了。
图 2-2
3. 隐藏帧的POST请求
前面的例子使用GET请求来从数据库中获取信息。由于客户ID能够以查询字符串的形式添加到URL中,因此十分简单。但如果需要发送POST请求该怎么办呢?它也可以使用隐藏帧技术,不过需要一些额外的工作。
POST请求通常是用于向服务器发送数据的场合,而与GET请求仅从服务器上获取数据不同。尽管GET请求可以通过查询字符串来向服务器发送额外的数据,但一些浏览器最多只能够处理512KB以内的查询字符串信息。对于POST请求而言,则可以发送2GB的信息,能够良好地满足绝大多数的应用。
从传统意义上说,只能够通过将表单的method属性设置为post来发送POST请求。然后,包含在表单中的数据就会通过POST请求发送到action属性中指定的URL上。更复杂的问题是当表单提交之后,将会从当前页跳转到一个新的URL上,这与Ajax的目的是背道而驰的。但万幸的是,可以通过表单中一个不太知名的target属性来简单实现。
<form/>元素的target属性的功能从某种意义上说与<a/>元素的target属性的功能类似:用来指定跳转的目的URL。通过设置表单元素的target属性,可以有效地使得在其他帧或窗口(在本例中是隐藏帧)中显示出表单的提交结果之后,表单页面仍然保持不变。
首先重新定义一个帧集。与上一个例子唯一不同的是可见帧包含了用来输入客户数据的表单:
| <frameset rows="100%,0" frameborder="0"> <frame name="displayFrame" src="entry.htm" noresize="noresize" /> <frame name="hiddenFrame" src="about:blank" noresize="noresize" /> </frameset> |
| <form method="post" action="SaveCustomer.php" target="hiddenFrame"> <p>Enter customer information to be saved:</p> <p>Customer Name: <input type="text" name="txtName" value="" /><br /> Address: <input type="text" name="txtAddress" value="" /><br /> City: <input type="text" name="txtCity" value="" /><br /> State: <input type="text" name="txtState" value="" /><br /> Zip Code: <input type="text" name="txtZipCode" value="" /><br /> Phone: <input type="text" name="txtPhone" value="" /><br /> E-mail: <input type="text" name="txtEmail" value="" /></p> <p><input type="submit" value="Save Customer Info" /></p> </form> <div id="divStatus"></div> |
| function saveResult(sMessage) { var divStatus = document.getElementById("divStatus"); divStatus.innerHTML = "Request completed: " + sMessage; } |
| <?php $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')"; //更多代码 ?> |
| <?php $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 = "Unable to open database"; if($oResult = mysql_query($sSQL)) { $sStatus = "Added customer; customer ID is ".mysql_insert_id(); } else { $sStatus = "An error occurred while inserting; customer not saved."; } mysql_close($oLink); ?> |
| <script type="text/javascript"> window.onload = function () { top.frames["displayFrame"].saveResult("<?php echo $sStatus ?>"); } </script> |

4. 隐藏iFrame
新一代的客户端—服务器通信模式幕后所采用的是iframe,它是在HTML 4.0中引入的。iframe与帧基本是相同的,唯一的区别是iframe可以放在一个未设置帧集的HTML页面中,可以使页面中的任意部分成为一个帧。iframe技术可以在未预先设置帧集的页面中使用,能够更好地适应于功能的逐渐添加。iframe甚至还可以使用JavaScript在运行时创建,为了简单起见,语义化HTML(semantic HTML)支持使浏览器将Ajax功能看作是一个有益的增强(这将在稍后讨论)。由于可以用与普通帧相同的方法使用和访问iframe,因此它们都是Ajax通信的理想选择。
发挥iframe的优势有两种方法。最简单的方法是在页面中简单地嵌入iframe,并像隐藏帧那样用来发出请求。为此,第一个例子中的显示页面将修改为:
| <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> <iframe src="about:blank" name="hiddenFrame" width="0" height="0" frameborder="0"></iframe> |
| window.onload = function () { var divInfoToReturn = document.getElementById("divInfoToReturn"); parent.displayCustomerInfo(divInfoToReturn.innerHTML); }; |
| function createIFrame() { var oIFrameElement = document.createElement("iframe"); oIFrameElement.width=0; oIFrameElement.height=0; oIFrameElement.frameBorder=0; oIFrameElement.name = "hiddenFrame"; oIFrameElement.id = "hiddenFrame"; document.body.appendChild(oIFrameElement); //更多代码 } |
| var oIFrame = null; function createIFrame() { var oIFrameElement = document.createElement("iframe"); oIFrameElement.width=0; oIFrameElement.height=0; oIFrameElement.frameBorder=0; oIFrameElement.name = "hiddenFrame"; oIFrameElement.id = "hiddenFrame"; document.body.appendChild(oIFrameElement); oIFrame = frames["hiddenFrame"]; } |
| function requestCustomerInfo() { if (!oIFrame) { createIFrame(); setTimeout(requestCustomerInfo, 10); return; } var sId = document.getElementById("txtCustomerId").value; oIFrame.location = "GetCustomerData.php?id=" + sId; } |
5. 隐藏iframe的POST请求
要使用隐藏iframe来完成POST请求,其方法是在隐藏帧中载入一个包含表单的页面,用数据填充该表单,然后再提交该表单。当这个可见的表单(你实际输入数据的那个)提交时,必须取消这次提交而将信息转发给隐藏帧。为此,必须定义一个函数,用来处理iframe的创建以及隐藏表单的载入:
| function checkIFrame() { if (!oIFrame) { createIFrame(); } setTimeout(function () { oIFrame.location = "ProxyForm.htm"; }, 10); } |
| <html> <head> <title>Proxy Form</title> <script type="text/javascript"> window.onload = function () { parent.formReady(); } </script> </head> <body> <form method="post"></form> </body> </html> |
| function formReady() { var oHiddenForm = oIFrame.document.forms[0]; var oForm = document.forms[0]; for (var i=0 ; i < oForm.elements.length; i++) { var oHidden = oIFrame.document.createElement("input"); oHidden.type = "hidden"; oHidden.name = oForm.elements[i].name; oHidden.value = oForm.elements[i].value; oHiddenForm.appendChild(oHidden); } oHiddenForm.action = oForm.action; oHiddenForm.submit(); }; |
| <form method="post" action="SaveCustomer.php" onsubmit="checkIFrame();return false"> <p>Enter customer information to be saved:</p> <p>Customer Name: <input type="text" name="txtName" value="" /><br /> Address: <input type="text" name="txtAddress" value="" /><br /> City: <input type="text" name="txtCity" value="" /><br /> State: <input type="text" name="txtState" value="" /><br /> Zip Code: <input type="text" name="txtZipCode" value="" /><br /> Phone: <input type="text" name="txtPhone" value="" /><br /> E-mail: <input type="text" name="txtEmail" value="" /></p> <p><input type="submit" value="Save Customer Info" /></p> </form> <div id="divStatus"></div> |