当在网上冲浪时,将在浏览器和服务器之间存在大量的请求。最初,所有的这种请求都是在用户做出需要这一步骤的明显操作时发生的。Ajax技术将开发人员从等待用户做出这样的操作中解放出来,允许他在任何时间创建一个对服务器的调用。
Ajax通信支持许多不同的技术。每一种技术都有自己的优点和缺点,因此了解什么情况使用哪一种技术是很重要的。
隐藏帧技术
随着HTML帧的引入,隐藏帧(hidden frame)技术也应运而生了。该技术后面的基本想法是创建一个帧集,其中包含用于客户端—服务器通信的隐藏帧。可以通过将帧的宽度或高度设置为0像素来隐藏一个帧,以使其不显示。尽管一些早期的浏览器(诸如Netscape 4)不能够完全隐藏帧,经常会留下一些明显的帧边框,但该技术还是广泛地为开发人员所采用。
1. 模式
隐藏帧技术遵循一种特定的四步模式(参见图2-1)。第一步总是从一个与用户交互的Web页面中的可见帧开始的。显然,用户并不知道隐藏帧的存在(在现代浏览器中,它是不显示的),以通常的形式与网页进行交互。在某些时间,用户执行了一个需要从服务器获取额外数据的操作。当这个操作发生时,第一步就发生了:产生一个对隐藏帧的JavaScript函数调用。这个调用可以简单地将隐藏帧重定向到另一个页面,或者复杂地传送表单数据。不管这个函数有多复杂,其结果都是产生第2步:向服务器发送一个请求。
图 2-1
该模式中的第3步是从服务器上接收一个响应。由于处理的是帧,因此该响应必然是另一个网页。该网页必须包含从服务器返回的所请求的数据,同时一些JavaScript将把这些数据传给可见的帧。通常,这是通过在返回的网页中分配一个onload事件处理函数(event handler)做到的,该网页在其全部载入之后调用可见帧中的函数(这就是第4步)。当数据位于可见帧中后,该帧就可以决定如何处理这些数据了。
2. 隐藏帧的GET请求
我们已经阐述了隐藏帧技术的基本原理,现在将更深入地研究它。对于任何一种新技术,最好的方法就是通过具体的实例来学习。在该实例中,将创建一个简单的查询页面,客户服务代表通过该页面可以查询客户的信息。由于这是本书的第一个例子,因此它十分的简单:用户输入客户ID,然后接收与该客户相关的信息。由于该功能通常需要数据库支持,因此还必须做一些服务器端的开发。该例子使用的是PHP——这是一种优秀的开源服务端语言,还将使用到MySQL(在从下载)——这是一种与PHP结合得很好的开源数据库。
尽管本例确定为使用MySQL,但只需少量的修改就可以在其他数据库上运行。
首先,在实现客户资料查询之前,你必须有一个包含该信息的数据库表。可以使用以下SQL脚本来创建一个客户表:
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';
在这张数据库表中最重要的字段是CustomerId,我们将通过它来查询客户信息。
你可以在下载这个脚本以及一些测试数据。
当建好数据库表后,就可以将精力转到HTML代码上了。要使用隐藏帧技术,首先必须创建一个HTML帧集,例如:
<frameset rows="100%,0" frameborder="0">
<frame src="display.htm" noresize="noresize" />
<frame src="about:blank" noresize="noresize" />
</frameset>
这部分代码中最重要的是<frameset/>元素的rows属性。通过将其设置为100%,0,浏览器就知道不显示名为hiddenFrame的第二个帧了。紧接着,将frameborder属性设置为0则是确保每个帧都没有可见的边框。在帧集声明中最后一个重要的步骤是为每个帧设置noresize属性,使得用户不可能在不经意间调整帧的大小而发现隐藏帧,隐藏帧的内容永远不会成为可显示的用户界面的一部分。
接下来要处理的是一个请求和显示客户信息的页面。这是一个相对简单的页面,由一个用来输入客户ID的文本框,一个执行请求的按钮,以及用来显示查询到的客户信息的<div>元素所组成:
<p>Enter customer ID number to retrieve information:</p>
<p>Customer ID: <input type="text" value="" /></p>
<p><input type="button" value="Get Customer Info"
onclick="requestCustomerInfo()" /></p>
<div></div>
注意,按钮调用的是名为requestCustomerInfo()的函数,该函数将负责与隐藏帧交互以获取数据。它将获取文本框中的值,将其添加到getcustomerdata.php的查询字符串上,以getcustomerdata.php?id=23的格式创建一个URL。然后将这个URL指派给隐藏帧,以下就是这个函数的代码:
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。
这是发出请求所需的所有信息。注意,由于这是一个GET请求(通过一个查询字符串传递信息),因此是很简单的。(很快,你将看到如何使用隐藏帧技术来执行一个POST请求。)
除了requestCustomerInfo()函数之外,还需要另一个在查询后显示客户信息的函数。当数据返回时,隐藏帧将调用这个displayCustomerInfo()函数,其唯一的参数是包含要显示的客户数据的字符串: