RSS
热门关键字:
当前位置 : 主页>编程开发>Python>列表

掌握AJAX之AJAX通讯技术简介

来源:我要研发网 作者: 时间:1970-01-01 点击:



  当在网上冲浪时,将在浏览器和服务器之间存在大量请求。最初,所有这种请求都是在用户做出需要这一步骤明显操作时发生。Ajax技术将开发人员从等待用户做出这样操作中解放出来,允许他在任何时间创建一个对服务器调用。 字串5

  Ajax通信支持许多不同技术。每一种技术都有自己优点和缺点,因此了解什么情况使用哪一种技术是很重要字串7

    隐藏帧技术 字串4

  随着HTML帧引入,隐藏帧(hidden frame)技术也应运而生了。该技术后面基本想法是创建一个帧集,其中包含用于客户端—服务器通信隐藏帧。可以通过将帧宽度或高度设置为0像素来隐藏一个帧,以使其不显示。尽管一些早期浏览器(诸如Netscape 4)不能够完全隐藏帧,经常会留下一些明显帧边框,但该技术还是广泛地为开发人员所采用。 字串5

  1. 模式

字串5

  隐藏帧技术遵循一种特定四步模式(参见图2-1)。第一步总是从一个与用户交互Web页面中可见帧开始。显然,用户并不知道隐藏帧存在(在现代浏览器中,它是不显示),以通常形式与网页进行交互。在某些时间,用户执行了一个需要从服务器获取额外数据操作。当这个操作发生时,第一步就发生了:产生一个对隐藏帧JavaScript函数调用。这个调用可以简单地将隐藏帧重定向到另一个页面,或者复杂地传送表单数据。不管这个函数有多复杂,其结果都是产生第2步:向服务器发送一个请求。 字串1

  

字串2

  图 2-1

字串1

  该模式中第3步是从服务器上接收一个响应。由于处理是帧,因此该响应必然是另一个网页。该网页必须包含从服务器返回所请求数据,同时一些JavaScript将把这些数据传给可见帧。通常,这是通过在返回网页中分配一个onload事件处理函数(event handler)做到,该网页在其全部载入之后调用可见帧中函数(这就是第4步)。当数据位于可见帧中后,该帧就可以决定如何处理这些数据了。

字串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属性,使得用户不可能在不经意间调整帧大小而发现隐藏帧,隐藏帧内容永远不会成为可显示用户界面一部分。

字串3


字串5

  接下来要处理是一个请求和显示客户信息页面。这是一个相对简单页面,由一个用来输入客户ID文本框,一个执行请求按钮,以及用来显示查询到客户信息<div>元素所组成:

字串4

<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嵌入到格式化字符串中。这将由主显示页面代码来完成。现在我们将创建服务器端程序逻辑。

字串2


字串4

  getcustomerdata.php中基本代码是在基本HTML页面上添加两处PHP代码:

字串9

<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变量,并将其设置为空字符串。在这段代码中所有其他变量,都包含了指定特定数据库配置信息,根据你自己实现环境将其替换为正确值。

字串8


字串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将填入一个错误消息。最后两行则负责释放数据库连接。

字串6

  关于更复杂PHP和MySQL编程阐述已超出了本文讨论范围。

字串5

  现在当$sInfo输出到<div/>元素时,它将包含正确信息。onload事件处理函数将读取这些数据,然后将其发送到显示帧上。如果查询到客户,其相应信息将会显示出来,如图2-2所示。

字串4


字串5

  另一方面,如果客户不存在,则会在屏幕相同位置显示错误消息。无论如何,客户服务代表都将获得一个很用户体验。你第一个Ajax程序也就完成了。 字串2

  

字串7

  图 2-2 字串9

  3. 隐藏帧POST请求

字串4

  前面例子使用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()。当隐藏帧返回客户数据保存结果时,将调用该函数:

字串2

function saveResult(sMessage) {
 var divStatus = document.getElementById("divStatus");
 divStatus.innerHTML = "Request completed: " sMessage;
}

  隐藏帧职责是向该函数传递一个消息,该消息将显示给用户。它可能是信息已保存确认信息,或者是说明为什么保存失败错误信息。

字串7

  接下来处理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语句,它将获取信息添加到数据库中。

字串4


字串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。由于该变量包含一个字符串,因此必须将PHPecho语句放在引号中。当执行该函数时,假设客户数据已保存,则输入表单页面看起来如图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,并像隐藏帧那样用来发出请求。为此,第一个例子中显示页面将修改为:

字串3

  <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。

字串1

  第一步很简单,使用document.createElement()方法创建iframe并赋予必要属性:

字串8

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是无法执行请求。另外注意,该iframename和id属性都是设置为hiddenFrame。这是必要,因为有些浏览器是通过name属性访问新帧,而有些则是通过id属性新帧。

字串7

  紧接着定义一个全局变量,用来保存对该帧对象引用。注意,针对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. 隐藏iframePOST请求

字串5

  要使用隐藏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()函数则是包含在主页面本身中,类似于:

字串3

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()函数将其添加到隐藏表单中。

字串4


字串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

最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册
相关文章