当在网上冲浪时,将在浏览器和服务器之间存在大量
请求。最初,所有
这种请求都是在用户做出需要这一步骤
明显操作时发生
。Ajax技术将开发人员从等待用户做出这样
操作中解放出来,允许他在任何时间创建一个对服务器
调用。 字串5
Ajax通信支持许多不同
技术。每一种技术都有自己
优点和缺点,因此了解什么情况使用哪一种技术是很重要
。 字串7
隐藏帧技术 字串4
随着HTML帧
引入,隐藏帧(hidden frame)技术也应运而生了。该技术后面
基本想法是创建一个帧集,其中包含用于客户端—服务器通信
隐藏帧。可以通过将帧
宽度或高度设置为0像素来隐藏一个帧,以使其不显示。尽管一些早期
浏览器(诸如Netscape 4)不能够完全隐藏帧,经常会留下一些明显
帧边框,但该技术还是广泛地为开发人员所采用。 字串5
1. 模式
字串5
隐藏帧技术遵循一种特定
四步模式(参见图2-1)。第一步总是从一个与用户交互
Web页面中
可见帧开始
。显然,用户并不知道隐藏帧
存在(在现代浏览器中,它是不显示
),以通常
形式与网页进行交互。在某些时间,用户执行了一个需要从服务器获取额外数据
操作。当这个操作发生时,第一步就发生了:产生一个对隐藏帧
JavaScript函数调用。这个调用可以简单地将隐藏帧重定向到另一个页面,或者复杂地传送表单数据。不管这个函数有多复杂,其结果都是产生第2步:向服务器发送一个请求。 字串1
字串2
图 2-1
该模式中
第3步是从服务器上接收一个响应。由于处理
是帧,因此该响应必然是另一个网页。该网页必须包含从服务器返回
所请求
数据,同时一些JavaScript将把这些数据传给可见
帧。通常,这是通过在返回
网页中分配一个onload事件处理函数(event handler)做到
,该网页在其全部载入之后调用可见帧中
函数(这就是第4步)。当数据位于可见帧中后,该帧就可以决定如何处理这些数据了。
字串8
2. 隐藏帧
GET请求
字串9
我们已经阐述了隐藏帧技术
基本原理,现在将更深入地研究它。对于任何一种新技术,最
方法就是通过具体
实例来学习。在该实例中,将创建一个简单
查询页面,客户服务代表通过该页面可以查询客户
信息。由于这是本书
第一个例子,因此它十分
简单:用户输入客户ID,然后接收与该客户相关
信息。由于该功能通常需要数据库支持,因此还必须做一些服务器端
开发。该例子使用
是PHP——这是一种优秀
开源服务端语言,还将使用到MySQL(在从www.mysql.org下载)——这是一种与PHP结合得很
开源数据库。 字串7
尽管本例确定为使用MySQL,但只需少量
修改就可以在其他数据库上运行。 字串5
首先,在实现客户资料查询之前,你必须有一个包含该信息
数据库表。可以使用以下SQL脚本来创建一个客户表: 字串9
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 DEFAULT CHARSET=GBK COMMENT='Sample Customer Data'; 在这张数据库表中最重要
字段是CustomerId,我们将通过它来查询客户信息。 字串9
你可以在www.wrox.com下载这个脚本以及一些测试数据。 字串2
当建
数据库表后,就可以将精力转到HTML代码上了。要使用隐藏帧技术,首先必须创建一个HTML帧集,例如:
字串1
<frameset rows="100%,0" frameborder="0">
<frame name="displayFrame" src="display.htm" noresize="noresize" />
<frame name="hiddenFrame" src="about:blank" noresize="noresize" />
</frameset> 这部分代码中最重要
是<frameset/>元素
rows属性。通过将其设置为100%,0,浏览器就知道不显示名为hiddenFrame
第二个帧了。紧接着,将frameborder属性设置为0则是确保每个帧都没有可见
边框。在帧集声明中最后一个重要
步骤是为每个帧设置noresize属性,使得用户不可能在不经意间调整帧
大小而发现隐藏帧,隐藏帧
内容永远不会成为可显示
用户界面
一部分。
字串5
接下来要处理
是一个请求和显示客户信息
页面。这是一个相对简单
页面,由一个用来输入客户ID
文本框,一个执行请求
按钮,以及用来显示查询到
客户信息
<div>元素所组成:
<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()
函数,该函数将负责与隐藏帧交互以获取数据。它将获取文本框中
值,将其添加到getcustomerdata.php
查询字符串上,以getcustomerdata.php?id=23
格式创建一个URL。然后将这个URL指派给隐藏帧,以下就是这个函数
代码: 字串3
function requestCustomerInfo() {
var sId = document.getElementById("txtCustomerId").value;
top.frames["hiddenFrame"].location = "getcustomerdata.php?id=" sId;
} 该函数
第一步是从文本框中获取客户标识号("txtCustomerId")。这是将文本框
ID txtCustomerId作为参数,调用document.getElementById()函数,并获取返回
value属性(value属性保存了文本框中
文本内容)来实现
。然后,将这个ID添加到字符串getcustomerdata.php?id=之后生成完整
URL。第二行代码则是创建此URL并将其赋给隐藏帧。为了获得对隐藏帧
引用,首先要使用top对象来获取浏览器
顶级窗口(topmost window)。该对象拥有一个frames数组,在其中可以找到这个隐藏帧。由于每个帧都是一个窗口对象,因此可以将其位置设置为预期
URL。 字串2
这是发出请求所需
所有信息。注意,由于这是一个GET请求(通过一个查询字符串传递信息),因此是很简单
。(很快,你将看到如何使用隐藏帧技术来执行一个POST请求。) 字串6
除了requestCustomerInfo()函数之外,还需要另一个在查询后显示客户信息
函数。当数据返回时,隐藏帧将调用这个displayCustomerInfo()函数,其唯一
参数是包含要显示
客户数据
字符串: 字串8
function displayCustomerInfo(sText) {
var divCustomerInfo = document.getElementById("divCustomerInfo");
divCustomerInfo.innerHTML = sText;
} 在这个函数中,第一行代码将查询对用于数据显示
<div/>元素
引用。第二行代码将把包含客户信息
字符串(sText)
值赋给<div/>元素
innerHTML属性。使用innerHTML属性,可以将HTML嵌入到格式化
字符串中。这将由主显示页面
代码来完成。现在我们将创建服务器端程序逻辑。
字串4
getcustomerdata.php中
基本代码是在基本
HTML页面上添加两处PHP代码:
<html>
<head>
<title>Get Customer Data</title>
<?php
//php代码
?>
</head>
<body>
<div id="divInfoToReturn"><?php echo $sInfo ?></div>
</body>
</html> 在该页面中,第一个PHP代码块将包括查询客户数据
逻辑(很快将讨论到)。而第二个PHP代码块则负责将包含客户数据
$sInfo变量
值输出到<div/>元素中。从这个<div/>元素中,你可以读取该数据并将数据传送给显示帧。为此,需要创建在页面完全载入后调用
JavaScript函数。 字串8
window.onload = function () {
var divInfoToReturn = document.getElementById("divInfoToReturn");
top.frames["displayFrame"].displayCustomerInfo(divInfoToReturn.innerHTML);
}; 该函数将直接赋给window.onload事件处理函数中。它首先获取对包含客户信息
<div/>元素
引用,然后使用数组top.frames访问显示帧,并调用前面定义
display CustomerInfo()函数,将其传给<div/>元素
innerHTML属性。这就是所有与发送该信息相关
JavaScript。但首先如何获取这些信息呢?需要一些PHP代码来从数据库查询信息。 字串7
在PHP代码中
第一步是定义所有需要
数据块。在本例中,这些数据块包括用来查询
客户ID、返回信息
$sInfo变量,以及访问数据库所需要
信息(数据库服务器、数据库名、用户名、密码以及SQL查询字符串): 字串8
<?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;
//更多代码
?> 这段代码首先从查询字符串中获取id参数。为了便于获取,PHP将所有
查询字符串参数组织于$-GET数组中。这个id存储在$sID中,它将用来创建存储于$sQuery中
SQL查询字符串。在此还将创建$sInfo变量,并将其设置为空字符串。在这段代码中
所有其他变量,都包含了指定特定数据库配置
信息,根据你自己
实现环境将其替换为正确
值。
字串1
获取了用户
输入,做
了连接数据库
基本准备,下一步就是创建数据库连接,执行查询,返回结果。如果存在一个指定ID
客户,$sInfo将填入包含所有数据
HTML字符串,包括对电子邮件地址创建一个链接,如果客户ID是无效
,那么$sInfo将填入错误消息,以传给显示帧: 字串4
<?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所示。
字串4
字串5
另一方面,如果客户不存在,则会在屏幕
相同位置显示错误消息。无论如何,客户服务代表都将获得一个很
用户体验。你
第一个Ajax程序也就完成了。 字串2
字串7
图 2-2 字串9
3. 隐藏帧
POST请求
前面
例子使用GET请求来从数据库中获取信息。由于客户ID能够以查询字符串
形式添加到URL中,因此十分简单。但如果需要发送POST请求该怎么办呢?它也可以使用隐藏帧技术,不过需要一些额外
工作。 字串7
POST请求通常是用于向服务器发送数据
场合,而与GET请求仅从服务器上获取数据不同。尽管GET请求可以通过查询字符串来向服务器发送额外
数据,但一些浏览器最多只能够处理512KB以内
查询字符串信息。对于POST请求而言,则可以发送2GB
信息,能够良
地满足绝大多数
应用。 字串6
从传统意义上说,只能够通过将表单
method属性设置为post来发送POST请求。然后,包含在表单中
数据就会通过POST请求发送到action属性中指定
URL上。更复杂
问题是当表单提交之后,将会从当前页跳转到一个新
URL上,这与Ajax
目
是背道而驰
。但万幸
是,可以通过表单中一个不太知名
target属性来简单实现。
字串2
<form/>元素
target属性
功能从某种意义上说与<a/>元素
target属性
功能类似:用来指定跳转
目
URL。通过设置表单元素
target属性,可以有效地使得在其他帧或窗口(在本例中是隐藏帧)中显示出表单
提交结果之后,表单页面仍然保持不变。
字串4
首先重新定义一个帧集。与上一个例子唯一不同
是可见帧包含了用来输入客户数据
表单: 字串2
<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/>元素,用来显示与客户端—服务器通信相关
状态信息:
字串5
字串5
<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,因此当用户点击该按钮时,提交
结果将显示在隐藏帧中。
字串8
在本例中,主页面中只需要一个JavaScript函数:savaResult()。当隐藏帧返回客户数据保存结果时,将调用该函数:
function saveResult(sMessage) {
var divStatus = document.getElementById("divStatus");
divStatus.innerHTML = "Request completed: " sMessage;
} 隐藏帧
职责是向该函数传递一个消息,该消息将显示给用户。它可能是信息已保存
确认信息,或者是说明为什么保存失败
错误信息。
接下来处理POST请求
文件是SavaCustomer.php。与前一个例子一样,该页面也是由简单
HTML页面加上一些PHP和JavaScript代码组成
。其中PHP代码用来从请求中收集信息,然后将其保存到数据库中。由于这是一个POST请求,因此$_POST数组中包含了提交
所有信息: 字串8
<?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语句,它将获取
信息添加到数据库中。
字串5
执行这个SQL语句
代码与上一个例子十分类似: 字串9
<?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.";
} 字串5
mysql_close($oLink);
?> 在此,mysql_query()函数
结果只是一个表示语句执行成功
指示器。如果执行成功, $sStatus变量中将填入一个消息,表明保存已经成功,并返回为该数据指定
客户ID。mysql_ insert_id()函数始终返回在最新
INSERT语句返回值
基础上自动递增
值。如果因为某些原因,该语句没有成功执行,$sStatus变量将填入一个错误消息。
字串7
$sStatus变量将输出到一个在载入窗口时运行
JavaScript函数中: 字串6
<script type="text/javascript">
window.onload = function () {
top.frames["displayFrame"].saveResult("<?php echo $sStatus ?>");
}
</script> 这段代码调用了savaResult()函数,该函数定义于显示帧中,传入
参数值是PHP变量$sStatus。由于该变量包含一个字符串,因此必须将PHP
echo语句放在引号中。当执行该函数时,假设客户数据已保存,则输入表单页面看起来如图2-3所示。
字串7
字串5
字串9
图 2-3 字串1
当执行这段代码之后,你还可以自由地使用同样
表单向数据库中添加更多客户,因为它不再消失。 字串4
4. 隐藏iFrame 字串3
新一代
客户端—服务器通信模式幕后所采用
是iframe,它是在HTML 4.0中引入
。iframe与帧基本是相同
,唯一
区别是iframe可以放在一个未设置帧集
HTML页面中,可以使页面中
任意部分成为一个帧。iframe技术可以在未预先设置帧集
页面中使用,能够更
地适应于功能
逐渐添加。iframe甚至还可以使用JavaScript在运行时创建,为了简单起见,语义化HTML(semantic HTML)支持使浏览器将Ajax功能看作是一个有益
增强(这将在稍后讨论)。由于可以用与普通帧相同
方法使用和访问iframe,因此它们都是Ajax通信
理想选择。 字串9
发挥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>
注意,这个iframe中
width、height和frameborder属性都设置成了0,这可将其从视线中隐去。由于iframe
名字仍是hiddenFrame,所以这个页面
JavaScript代码可以如前一样正常工作。不过,对于GetCustomerData.php页面还需要做一些小
修改。在该页面中
JavaScript函数先前是在名为displayFrame
帧中查找displayCustomerInfo()函数。如果你使用该技术,又不存在该名字
帧,则必须修改代码,用parent来代替它: 字串8
字串7
window.onload = function () {
var divInfoToReturn = document.getElementById("divInfoToReturn");
parent.displayCustomerInfo(divInfoToReturn.innerHTML);
}; 现在这个例子能够和本文中
第一例子一样正常工作了。 字串4
第二种使用隐藏iframe
方法是通过JavaScript动态地创建它们。由于并非所有浏览器实现iframe
方法都是一样
,所以需要一些技巧,使得它有助于一步步地创建隐藏
iframe。
第一步很简单,使用document.createElement()方法创建iframe并赋予必要
属性:
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);
//更多代码
} 本段代码
最后一行很重要,因为它将iframe添加到document结构中;没有添加到document中
iframe是无法执行请求
。另外注意,该iframe
name和id属性都是设置为hiddenFrame。这是必要
,因为有些浏览器是通过name属性访问新
帧,而有些则是通过id属性新
帧。
紧接着定义一个全局变量,用来保存对该帧对象
引用。注意,针对iframe元素
这个帧对象并非是从createElement()函数返回
。要获得该对象,必须从帧集合中获取。以下就是即将保存在全局变量中
内容: 字串1
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"];
} 如果你将这些代码放到前面
iframe例子中,那么需要对requestCustomerInfo()函数进行如下修改:
字串6
function requestCustomerInfo() {
if (!oIFrame) {
createIFrame();
setTimeout(requestCustomerInfo, 10);
return;
}
var sId = document.getElementById("txtCustomerId").value;
oIFrame.location = "GetCustomerData.php?id=" sId;
} 基于这些修改,该函数将会检查oIFrame是否为空。如果为空,则调用createFrame(),并会为该函数
调用设置10ms
超时时间。这是很必要
,因为只有IE浏览器能够立即识别插入
iframe,大部分其他浏览器需要花几毫秒来识别它,以允许通过它发送请求。当再次执行该函数时,将执行代码
其余部分,其中最后一行已经修改为对OIFrame对象
引用。 字串3
字串9
尽管该技术能够很容易地应用于GET请求,但POST请求却完全不同。只有一部分浏览器允许你设置表单
target属性来动态创建iframe;但IE并不是其中
一种。因此,要使用隐藏iframe技术来发送POST请求还需要一些技巧。 字串1
5. 隐藏iframe
POST请求
要使用隐藏iframe来完成POST请求,其方法是在隐藏帧中载入一个包含表单
页面,用数据填充该表单,然后再提交该表单。当这个可见
表单(你实际输入数据
那个)提交时,必须取消这次提交而将信息转发给隐藏帧。为此,必须定义一个函数,用来处理iframe
创建以及隐藏表单
载入: 字串4
function checkIFrame() {
if (!oIFrame) {
createIFrame();
}
setTimeout(function () {
oIFrame.location = "ProxyForm.htm";
}, 10);
} 这个名为checkIFrame()
函数首先检查隐藏
iframe是否已经创建。如果没有,则调用createIFrame()。然后,在将iframe
地址设置为ProxyForm.htm(这是一个隐藏表单页面)之前,为其设置一个超时值。由于该函数调用需要花一些时间,而重要
是该页面每次加载时都将提交该表单。
字串3
ProxyForm.htm文件很简单,只包括很少
JavaScript,用来提示主页面已经装载完成:
字串1
<html>
<head>
<title>Proxy Form</title>
<script type="text/javascript">
window.onload = function () {
parent.formReady();
}
</script>
</head>
<body>
<form method="post"></form>
</body>
</html> 正如你所见,该页面
主体只包含一个空
表单,而标题中只包含一个onload事件处理函数。当载入该页面时,页面将通过调用parent.formReady()来使主页面知道它已经做
接收请求
准备。而formReady()函数则是包含在主页面本身中
,类似于:
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();
}; 在该函数中
第一步是获取对隐藏iframe中表单
引用,可以通过访问该帧
document.forms集合来获取。由于在该页面中只有一个表单,因此可以安全地从该集合中获得第一个表单(即索引值为0),并将其存储于oHiddenForm中。然后,将对主页面表单
引用存于oForm中。紧接着,一个for循环对主页面中该表单
各元素进行遍历(使用elements集合)。对于表单中
每一个元素,都将在隐藏帧(注意,必须使用oIFrame.document.createElement()而不只是document.createElement())中创建一个隐藏
输入元素。这个隐藏
输入元素拥有与该表单元素相同
名字和值,然后使用appendChild()函数将其添加到隐藏
表单中。
字串8
当所有
表单元素都添加完后,隐藏
表单还将设置与主页面表单相同
action。通过从表单中读取action来取代硬编码,就可以在任何页面中使用formReady()。该函数
最后一步是提交这个隐藏
表单。 字串1
剩下
最后一件事就是确保主页面
表单不以通常
方式提交自己。要达到这一目标,只需在onsubmit事件处理函数中调用checkIFrame()并返回false: 字串3
<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> 通过以这种方式返回flase,可以阻止表单
默认行为(将自己提交到服务器)。通过调用checkIFrame()方法来启动隐藏iframe中表单
提交进程。 字串7
当这一任务完成后,就可以像使用隐藏帧POST请求
例子一样使用本例;页面SavaCustomer.php负责处理数据,并当完成时调用主页面中
savaResult()函数。 字串1
注意,本节中
例子是为了使其聚焦于与Ajax技术相关
问题上,因而进行了简化。如果在实际
Web应用程序中使用,还需要提供更多
用户反馈,诸如在发出请求时屏蔽该表单
输入等。 字串9
6. 隐藏帧技术
优点和缺点
字串2
现在,你已经对使用隐藏帧所实现
强大功能有所了解了,我们将讨论它
实用性。正如前面所说
,该技术已经存在多年,并且仍然在许多Ajax应用中使用。
字串2
字串8
使用隐藏帧
一个最大理由之一是它可以维护浏览器
历史,使用户仍然能够使用浏览器上
后退和前进按钮。浏览器由于并不知道隐藏帧实际上被隐藏了,但对于其所发出
请求仍然是记录在案
。然而,Ajax应用程序
主页面却没有修改,在隐藏帧中
修改意味着后退和前进按钮将依据该隐藏帧
访问历史而非主页面而变化。这也是为什么Gmail和Google Maps仍然使用该技术
理由。 字串3
注意,iframe并非一直会存储浏览器
历史记录。尽管IE始终会存储iframe
历史记录,但Firefox只对使用HTML定义(也就是不包括使用JavaScript动态创建)
iframe保存历史记录。Safari从不为iframe保存历史记录,不管它们是如何包含在该页面中
。
字串4
隐藏帧技术不利
一面是,对其背后发生
事了解甚少。它完全依赖于返回
正确页面。本节
例子都存在相同
问题:如果隐藏帧
页面载入失败,并不会向用户提示出错消息;主页面将继续等待直到调用适当
JavaScript函数。必须通过设置一个较长周期(可能是5分钟)
超时时间,然后如果页面仍然没有成功载入则显示一条消息,以给用户一个安慰。但这一切都只是一个变通方法,最主要
问题是,对于后台发生
HTTP请求缺乏充足
信息。幸运
,我们还有其他选择。 字串7
字串9
![我要研发网[www.51dev.com]](/templets/images/toplogo.gif)
