投递文章投递文章 投稿指南投稿指南 RSS订阅RSS订阅

Ajax基础教程(阿斯利森版)第二章

来源:CSDN 发布时间:2008-05-14 收藏 投稿 字体:【
2.1 XMLHttpRequest对象概述 代码清单2-1 创建XMLHttpRequest对象的一个实例 var xmlHttp; function createXMLHttpRequest() { if (window.ActiveXObject) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); } } 可以看到,创建XMLHttpRequest对象相当容易。首先,要创建一个全局作用域变量xmlHttp来保存这个对象的引用。createXMLHttpRequest方法完成创建XMLHttpRequest实例的具体工作。这个方法中只有简单的分支逻辑(选择逻辑)来确定如何创建对象。对window.ActiveXObject的调用会返回一个对象,也可能返回null,if语句会把调用返回的结果看作是true或false(如果返回对象则为true,返回null则为false),以此指示浏览器是否支持ActiveX控件,相应地得知浏览器是不是Internet Explorer。如果确实是,则通过实例化ActiveXObject的一个新实例来创建XMLHttpRequest对象,并传入一个串指示要创建何种类型的ActiveX对象。在这个例子中,为构造函数提供的字符串是Microsoft.XMLHTTP,这说明你想创建XMLHttpRequest的一个实例。 如果window.ActiveXObject调用失败(返回null),JavaScript就会转到else语句分支,确定浏览器是否把XMLHttpRequest实现为一个本地JavaScript对象。如果存在window. XMLHttpRequest,就会创建XMLHttpRequest的一个实例。 由于JavaScript具有动态类型特性,而且XMLHttpRequest在不同浏览器上的实现是兼容的,所以可以用同样的方式访问XMLHttpRequest实例的属性和方法,而不论这个实例创建的方法是什么。这就大大简化了开发过程,而且在JavaScript中也不必编写特定于浏览器的逻辑。 2.2 方法和属性 表2-1显示了XMLHttpRequest对象的一些典型方法。不要担心,稍后就会详细介绍这些方法。 表2-1 标准XMLHttpRequest操作

   

   

abort()

停止当前请求

getAllResponseHeaders()

HTTP请求的所有响应首部作为键/值对返回

getResponseHeader("header")

返回指定首部的串值

open("method", "url")

建立对服务器的调用。method参数可以是GETPOSTPUTurl参数可以是相对URL或绝对URL。这个方法还包括3个可选的参数

send(content)

向服务器发送请求

setRequestHeader("header", "value")

把指定首部设置为所提供的值。在设置任何首部之前必须先调用open()

下面来更详细地讨论这些方法。

void open(string method, string url, boolean asynch, string username, string password):这个方法会建立对服务器的调用。这是初始化一个请求的纯脚本方法。它有两个必要的参数,还有3个可选参数。要提供调用的特定方法(GET、POST或PUT),还要提供所调用资源的URL。另外还可以传递一个Boolean值,指示这个调用是异步的还是同步的。默认值为true,表示请求本质上是异步的。如果这个参数为false,处理就会等待,直到从服务器返回响应为止。由于异步调用是使用Ajax的主要优势之一,所以倘若将这个参数设置为false,从某种程度上讲与使用XMLHttpRequest对象的初衷不太相符。不过,前面已经说过,在某些情况下这个参数设置为false也是有用的,比如在持久存储页面之前可以先验证用户的输入。最后两个参数不说自明,允许你指定一个特定的用户名和密码。

void send(content):这个方法具体向服务器发出请求。如果请求声明为异步的,这个方法就会立即返回,否则它会等待直到接收到响应为止。可选参数可以是DOM对象的实例、输入流,或者串。传入这个方法的内容会作为请求体的一部分发送。

void setRequestHeader(string header, string value):这个方法为HTTP请求中一个给定的首部设置值。它有两个参数,第一个串表示要设置的首部,第二个串表示要在首部中放置的值。需要说明,这个方法必须在调用open()之后才能调用。

在所有这些方法中,最有可能用到的就是open()和send()。XMLHttpRequest对象还有许多属性,在设计Ajax交互时这些属性非常有用。

void abort():顾名思义,这个方法就是要停止请求。

string getAllResponseHeaders():这个方法的核心功能对Web应用开发人员应该很熟悉了,它返回一个串,其中包含HTTP请求的所有响应首部,首部包括Content-
Length、Date和URI。

string getResponseHeader(string header):这个方法与getAllResponseHeaders()是对应的,不过它有一个参数表示你希望得到的指定首部值,并且把这个值作为串返回。

除了这些标准方法,XMLHttpRequest对象还提供了许多属性,如表2-2所示。处理XMLHttpRequest时可以大量使用这些属性。

表2-2 标准XMLHttpRequest属性

属    性
 描    述
 
onreadystatechange
 每个状态改变时都会触发这个事件处理器,通常会调用一个JavaScript函数
 
readyState
 请求的状态。有5个可取值:0 = 未初始化,1 = 正在加载,2 = 已加载,3 = 交互中,4 = 完成
 
responseText
 服务器的响应,表示为一个串
 
responseXML
 服务器的响应,表示为XML。这个对象可以解析为一个DOM对象
 
status
 服务器的HTTP状态码(200对应OK,404对应Not Found(未找到),等等)
 
statusText
 HTTP状态码的相应文本(OK或Not Found(未找到)等等)
 

2.3 交互示例  

看到这里,你可能想知道典型的Ajax交互是什么样。图2-1显示了Ajax应用中标准的交互模式。

2-1 标准Ajax交互

不同于标准Web客户中所用的标准请求/响应方法,Ajax应用的做法稍有差别。

1. 一个客户端事件触发一个Ajax事件。从简单的onchange事件到某个特定的用户动作,很多这样的事件都可以触发Ajax事件。可以有如下的代码:

<input type="text"d="email" name="email" onblur="validateEmail()";>

2. 创建XMLHttpRequest对象的一个实例。使用open()方法建立调用,并设置URL以及所希望的HTTP方法(通常是GETPOST)。请求实际上通过一个send()方法调用触发。可能的代码如下所示:

var xmlHttp;

function validateEmail() {

   var email = document.getElementById("email");

   var url = "validate?email=" + escape(email.value);

   if (window.ActiveXObject) {

     xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

   }

   else if (window.XMLHttpRequest) {

     xmlHttp = new XMLHttpRequest();

   }

xmlHttp.open("GET", url);

xmlHttp.onreadystatechange = callback;

xmlHttp.send(null);

}

3. 向服务器做出请求。可能调用servletCGI脚本,或者任何服务器端技术。

4. 服务器可以做你想做的事情,包括访问数据库,甚至访问另一个系统。

5. 请求返回到浏览器。Content-Type设置为text/xml——XMLHttpRequest对象只能处理text/html类型的结果。在另外一些更复杂示例中,响应可能涉及更广,还包括JavaScriptDOM管理以及其他相关的技术。需要说明,你还需要设置另外一些首部,使浏览器不会在本地缓存结果。为此可以使用下面的代码:

response.setHeader("Cache-Control", "no-cache");

response.setHeader("Pragma", "no-cache");[1]

6. 在这个示例中,XMLHttpRequest对象配置为处理返回时要调用callback()函数。这个函数会检查XMLHttpRequest对象的readyState属性,然后查看服务器返回的状态码。如果一切正常,callback()函数就会在客户端上做些有意思的工作。以下就是一个典型的回调方法:

function callback() {

   if (xmlHttp.readyState == 4) {

     if (xmlHttp.status == 200) {

          //do something interesting here

     }

   }

}

可以看到,这与正常的请求/响应模式有所不同,但对Web开发人员来说,并不是完全陌生的。显然,在创建和建立XMLHttpRequest对象时还可以做些事情,另外当“回调”函数完成了状态检查之后也可以有所作为。一般地,你会把这些标准调用包装在一个库中,以便在整个应用中使用,或者可以使用Web上提供的库。这个领域还很新,但是在开源社区中已经如火如荼地展开了大量的工作。

通常,Web上提供的各种框架和工具包负责基本的连接和浏览器抽象,有些还增加了用户界面组件。有一些纯粹基于客户,还有一些需要在服务器上工作。这些框架中的很多只是刚开始开发,或者还处于发布的早期阶段,随着新的库和新的版本的定期出现,情况还在不断发生变化。这个领域正在日渐成熟,最具优势的将脱颖而出。一些比较成熟的库包括libXmlRequestRSLitesarissaJavaScript对象注解(JavaScript Object NotationJSON)、JSRS、直接Web远程通信(Direct Web RemotingDWR)和Rails on Ruby。这个领域日新月异,所以应当适当地配置你的RSS收集器,及时收集有关Ajax的所有网站上的信息!

2.4 GET与POST 

你可能想了解GETPOST之间有什么区别,并想知道什么时候使用它们。从理论上讲,如果请求是幂等的就可以使用GET,所谓幂等是指多个请求返回相同的结果。实际上,相应的服务器方法可能会以某种方式修改状态,所以一般情况下这是不成立的。这只是一种标准。更实际的区别在于净荷的大小,在许多情况下,浏览器和服务器会限制URL的长度URL用于向服务器发送数据。一般来讲,可以使用GET从服务器获取数据;换句话说,要避免使用GET调用改变服务器上的状态。

一般地,当改变服务器上的状态时应当使用POST方法。不同于GET,需要设置XML- HttpRequest对象的Content-Type首部,如下所示:

xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

GET不同,POST不会限制发送给服务器的净荷的大小,而且POST请求不能保证是幂等的。

你做的大多数请求可能都是GET请求,不过,如果需要,也完全可以使用POST

2.5 远程脚本

我们已经介绍了Ajax,下面来简单谈谈远程脚本。你可能会想:“Ajax有什么大不了的?我早就用IFRAME做过同样的事情。”实际上,我们自己也曾用过这种方法。这在以前一般称为远程脚本remote scripting),很多人认为这只是一种修修补补。不过,这确实提供了一种能避免页面刷新的机制。

2.5.1  远程脚本概述

基本说来,远程脚本是一种远程过程调用类型。你可以像正常的Web应用一样与服务器交互,但是不用刷新整个页面。与Ajax类似,你可以调用任何服务器端技术来接收请求、处理请求并返回一个有意义的结果。正如在服务器端有很多选择,客户端同样有许多实现远程脚本的选择。你可以在应用中嵌入Flash动画、Java applet,或者ActiveX组件,甚至可以使用XML-RPC,但是这种方法过于复杂,因此除非你使用这种技术很有经验,否则这种方法不太合适。实现远程脚本的通常做法包括将脚本与一个IFRAME(隐藏或不隐藏)结合,以及由服务器返回JavaScript,然后再在浏览器中运行这个JavaScript

Microsoft提供了自己的远程脚本解决方案,并聪明地称之为Microsoft远程脚本(Microsoft Remote ScriptingMSRS)。采用这种方法,可以像调用本地脚本一样调用服务器脚本。页面中嵌入Java applet,以便与服务器通信,.asp页面用于放置服务器端脚本,并用.htm文件管理客户端的布局摆放。在NetscapeIE 4.0及更高版本中都可以使用Microsoft的这种解决方案,可以同步调用,也可以异步调用。不过,这种解决方案需要Java,这意味着可能还需要附加的安装例程,而且还需要Internet Information ServicesIIS),因此会限制服务器端的选择。

Brent Ashley为远程脚本创建了两个免费的跨平台库。JSRS是一个客户端JavaScript库,它充分利用DHTML向服务器做远程调用。相当多的操作系统和浏览器上都能使用JSRS。如果采用一些常用的、流行的服务器端实现(如PHPPythonPerl CGI),JSRS一般都能在网站上安装并运行。Ashley免费提供了JSRS,而且还可以从他的网站(www.ashleyit.com
/rs/main.htm
上得到源代码

如果你觉得JSRS太过笨重,Ashley还创建了RSLite,这个库使用了cookieRSLite仅限于少量数据和单一调用,不过大多数浏览器都能提供支持。

2.5.2  远程脚本的示例

为了进行比较,这里向你展示如何使用IFRAME来实现类似Ajax的技术。这非常简单,而且过去我们就用过这种方法(在XMLHttpRequest问世之前)。这个示例并没有真正调用服务器,只是想让你对如何使用IFRAME实现远程脚本有所认识。

这个示例包括两个文件:iframe.html(见代码清单2-2)和server.html(见代码清2-3)。server.html模拟了本应从服务器返回的响应。

代码清单2-2 iframe.html文件

<html>

   <head>

     <title>Example of remote scripting in an IFRAME</title>

   </head>

   <script type="text/javascript">

     function handleResponse() {

       alert('this function is called from server.html');

     }

   </script>

   <body>

   <h1>Remote Scripting with an IFRAME</h1>

 

   <iframe id="beforexhr"

   name="beforexhr"

   style="width:0px; height:0px; border: 0px"

   src="blank.html"></iframe>

 

   <a href="server.html" target="beforexhr">call the server</a>

 

   </body>

</html>

代码清单2-3 server.html文件

<html>

   <head>

     <title>the server</title>

   </head>

   <script type="text/javascript">

     window.parent.handleResponse();

   </script>

   <body>

   </body>

</html>

2-2显示了最初的页面。运行这个代码生成的结果如图2-3所示。

2-2 最初的页面

2-3 调用“服务器”之后的页面

2.6 如何发送简单请求

现在已经准备开始使用XMLHttpRequest对象了。我们刚刚讨论了如何创建这个对象,下面来看如何向服务器发送请求,以及如何处理服务器的响应。

最简单的请求是,不以查询参数或提交表单数据的形式向服务器发送任何信息。在实际中,往往都希望向服务器发送一些信息。

使用XMLHttpRequest对象发送请求的基本步骤如下:

1. 得到XMLHttpRequest对象实例的一个引用,可以创建一个新的实例,也可以访问包含有XMLHttpRequest实例的一个变量。

2. 告诉XMLHttpRequest对象,哪个函数会处理XMLHttpRequest对象状态的改变,为此要把对象的onreadystatechange属性设置为指向JavaScript函数的指针。

3. 指定请求的属性。XMLHttpRequest对象的open()方法会指定将发出的请求。open()方法取3个参数:一个是指示所用方法(通常是GETPOST)的串;一个是表示目标资源URL的串;一个是Boolean值,指示请求是否是异步的。

4. 将请求发送给服务器。XMLHttpRequest对象的send()方法把请求发送到指定的目标资源。send()方法接受一个参数,通常是一个串或一个DOM对象。这个参数作为请求体的一部分发送到目标URL。当向send()方法提供参数时,要确保open()中指定的方法是POST。如果没有数据作为请求体的一部分被发送,则使用null

这些步骤很直观:你需要XMLHttpRequest对象的一个实例,要告诉它如果状态有变化该怎么做,还要告诉它向哪里发送请求以及如何发送请求,最后还需要指导XMLHttpRequest发送请求。不过,除非你对CC++很了解,否则可能不明白函数指针function pointer)是什么意思。

函数指针与任何其他变量类似,只不过它指向的不是像串、数字、甚至对象实例之类的数据,而是指向一个函数。在JavaScript中,所有函数在内存中都编有地址,可以使用函数名引用。这就提供了很大的灵活性,可以把函数指针作为参数传递给其他函数,或者在一个对象的属性中存储函数指针。

对于XMLHttpRequest对象,onreadystatechange属性存储了回调函数的指针。当XMLHttpRequest对象的内部状态发生变化时,就会调用这个回调函数。当进行了异步调用,请求就会发出,脚本立即继续处理(在脚本继续工作之前,不必等待请求结束)。一旦发出了请求,对象的readyState属性会经过几个变化。尽管针对任何状态都可以做一些处理,不过你最感兴趣的状态可能是服务器响应结束时的状态。通过设置回调函数,就可以有效地告诉XMLHttpRequest对象:“只要响应到来,就调用这个函数来处理响应。”

最新5条评论 查看所有评论
评论内容:请自觉遵守互联网相关政策法规。
用户名: 密码: 匿名 注册
About iTtang - 联系方法  - 专题列表 - 友情链接  -  高级搜索   -  帮助中心  -