【转】退而求其次的选择1:使用IFrame发送请求《深入理解Ajax:基于JavaScript的RIA开发 》

IFrames为异步调用提供了一个合适的 传输途径,因为它们可以在不使整个页面重新装载的基础上载入新内容,而新的IFrame元素则可以通过JavaScript创建。IFrame最好的属性 之一是表单可以将其作为目标,从而只需重载IFrame而不用对整个页面进行重载; 该方法可以通过POST类型请求将大量数据发送给服务器。

在使用IFrame作为传输方法时,其中的 一个难点是载入的页面必须是HTML格式的,并且在载入完成时,需要通过JavaScript的onload事件句柄来告诉其父文档。这就使得基于 IFrames发出的所有请求所针对的页面都必须是针对IFrame请求设计的(其代码无法像在XMLHttpRequest方法中那样获取一个XML文 件)。

注意,使用IFrames还有许多其他限制:

·  只支持异步请求;

·  需要修改服务器端页面;

·  会在浏览器的历史中加上虚构的项;

·  在某些浏览器上,会使后退、前进按钮的行为变得不确定;

·  在不同浏览器中的实现有巨大的不同,特别是在老版本的浏览器中。

IFrame和 XMLHttpRequest相比也有一个优点,即可以用来完成文件上传。由于浏览器的安全限制,只有诸如单击表单的用户操作可以与用户机器上的文件交 互。可以仅对文件上传使用目标为一个IFrame的表单,它不涉及常规的表单POST操作和页面重载周期。不过,这不是针对文件上传使用IFrame,而 对其他Ajax请求则使用XMLHttpRequest的理由。除非发起的是远程脚本风格的Ajax请求(这将在第3章中讲述),对于IFrame的限 制,会使所有Ajax开发项目的工作量大大增加。

1  创建一个隐藏IFrame

为了最大程度上与老版本浏览器兼容,可以在HTML中添加IFrame并将其大小设置为0x0(不能仅是隐藏它,否则有些浏览器将不会载入它)。不过该方 法的灵活性并不好,因此应该动态地创建这个帧。并非所有老版本的浏览器都支持document.createElement方法,但不支持该方法的浏览器 通常也不具备在载入数据时所需的其他动态能力,因此对于它们最好是提供一个静态HTML版本的页面。在下面的例子中,使用innerHTML创建了这个 IFrame,因为它比使用DOM方法更简单。注意,这里也使用了document.createElement方法,用来添加div元素:

2  创建一个表单

如果要发起GET请求,只需修改 IFrames中src属性的值,但进行POST请求时则需要使用一个目标表单。GET方法并不是Ajax请求的良好解决方案,主要有两个原因:它能够发 送的数据是有限的(具体的数据量限制取决于浏览器),GET请求会被代理服务器缓存且/或预载入,因此决不要用它来执行诸如数据库更新之类的操作。

在IFrame中使用一个表单是很简单的。只要设置表单的target属性即可,当提交该表单时,其结果就将在该IFrame中载入。以下例子创建了我们的表单,并将其target属性设置为在第2.5.1节中创建的IFrame:

3  从载入的内容向原始文档发送数据

要知道IFrame的内容已经载入的唯一方 法是在内容页上运行一些JavaScript代码,以提示IFrame所嵌入的父页面。完成该任务的最简单方法是设置载入文档的onload事件句柄。这 一限制意味着使用IFrame不能像使用XMLHttpRequest那样载入任意的内容。不过,当某个页面已被作为Ajax网关时,该方法仍然是很有效 的。以下就是一个onload事件句柄的实例:

4  基于IFrame的Ajax完整实例

一个完整的基于IFrame的Ajax实例中的请求包含两个部分内容。第一部分是客户端代码,用来创建IFrame和表单;第二部分是服务器端代码,它负责准备数据,并通过父文档的onload事件句柄将其发送回去。

本例的第1部分(程序清单2-5所示)是位 于一个简单HTML文件中的JavaScript代码。该页面用于测试;回调函数只是在警告对话框中显示出结果。该例子的第2部分(程序清单2-6所示) 是一个简单的PHP脚本,它负责从POST请求中获取数据,并将其回送给父文档。为实现一个实际有效的系统,可能需要在表单中添加一些其他变量,以告诉 PHP代码如何处理上传的数据,或者可以在脚本中直接加入业务逻辑,并对要实现的每个任务都设置一个不同的目标页。

程序清单2-5  使用IFrame发送一个Ajax请求

程序清单2-5中包含3个函数:

·  createRemotingDiv  用来设置IFrame。

·  sendRequest  用来发起Ajax请求。

·  test  发起Ajax请求。test函数在页面的HTML代码中与一个链接绑定在一起。用户点击该链接,将启动一个Ajax请求。

函数 createRemotingDiv中所包含的代码在前面已经描述过了,它包括的代码用来创建隐藏IFrame以及将向其提交信息的表 单。在表单创建完后,其目标将是新创建的IFrame,用表单提交代替当前页面的重载。开发时,经常在调试过程中显示IFrame,这是很有效的,因为可 以看到调用的页面所生成的输出。要实现该目标,可以将第8行修改为“width:200;height:200”。

函数sendRequest用来发起Ajax请求。其参数包括请求将发向的URL、发送给服务器的payload,以及请求完成时将执行的回调函数。该函数使用 createRemotingDiv来配置这一过程。然后sendRequest将更新IFrame表单的操作,把 payload值填充到表单中,使用IFrame提交该表单。当在IFrame中载入了新页面时,新文档将通过JavaScript的onload句柄调 用已传给sendRequest方法的回调函数。这个处理POST表单的PHP页面,以及创建onload句柄的JavaScript代码如程序清单 2-6所示。

程序清单2-6  处理基于IFrame的Ajax请求的PHP服务器端页面

在服务器端,该表单将被处理,并将以HTML页面的形式创建输出。添加新数据的最简单方法是生成包含新数据的JavaScript。在这里,我们只是通过 为result变量赋值的方法,将数据回显给客户端。通常,在此会运行服务器端代码,或者输出一个字符(就像本例这样),或者添加将在父文 档中执行的新JavaScript代码。父文档的回调函数是在body标签的onload事件句柄中定义的。

 

注意: 以上JS代码在插入的时候可能自动添加了mce字样,调试时请自行去除~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值