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/>元素中,而且针对保存在数据库中的每个字段都有一个相应的文本框(除了自动生成的客户ID之外)。同样也有一个<div/>元素,用来显示与客户端—服务器通信相关的状态信息:
<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> |
注意,<form/>元素的target属性也设置为hiddenFrame,因此当用户点击该按钮时,提交的结果将显示在隐藏帧中。
在本例中,主页面中只需要一个JavaScript函数:savaResult()。当隐藏帧返回客户数据保存结果时,将调用该函数:
function saveResult(sMessage) {
var divStatus = document.getElementById("divStatus");
divStatus.innerHTML = "Request completed: " + sMessage;
} |
隐藏帧的职责是向该函数传递一个消息,该消息将显示给用户。它可能是信息已保存的确认信息,或者是说明为什么保存失败的错误信息。
接下来处理POST请求的文件是SavaCustomer.php。与前一个例子一样,该页面也是由简单的HTML页面加上一些PHP和JavaScript代码组成的。其中PHP代码用来从请求中收集信息,然后将其保存到数据库中。由于这是一个POST请求,因此$_POST数组中包含了提交的所有信息:
<?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')";
//更多代码
?> |
这个代码片段将获取与客户相关的所有POST信息;此外,还定义了一个状态消息($sStatus)以及所需的数据库信息(与上一个例子相同)。这里的SQL语句是一个INSERT语句,它将获取的信息添加到数据库中。
执行这个SQL语句的代码与上一个例子十分类似:
<?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);
?> |
在此,mysql_query()函数的结果只是一个表示语句执行成功的指示器。如果执行成功, $sStatus变量中将填入一个消息,表明保存已经成功,并返回为该数据指定的客户ID。mysql_ insert_id()函数始终返回在最新的INSERT语句返回值的基础上自动递增的值。如果因为某些原因,该语句没有成功执行,$sStatus变量将填入一个错误消息。
$sStatus变量将输出到一个在载入窗口时运行的JavaScript函数中:
<script type="text/javascript">
window.onload = function () {
top.frames["displayFrame"].saveResult("<?php echo $sStatus ?>");
}
</script> |
这段代码调用了savaResult()函数,该函数定义于显示帧中,传入的参数值是PHP变量$sStatus。由于该变量包含一个字符串,因此必须将PHP的echo语句放在引号中。当执行该函数时,假设客户数据已保存,则输入表单页面看起来如图2-3所示。

图 2-3
当执行这段代码之后,你还可以自由地使用同样的表单向数据库中添加更多客户,因为它不再消失。 |