11.3.5 处理来自服务器的数据

Ajax通常是一条双向大道,JavaScript程序向服务器发送一些数据,而服务器向JavaScript程序返回一些数据,然后可以使用这些数据来更新页面。在上一节中,我们看到了如何格式化数据并使用get()和post()函数将其发送给服务器。现在,我们来学习如何接收和处理服务器的响应。

当Web浏览器使用XMLHttpRequest对象向服务器发送完一个请求,它保持对来自服务器的响应的监听。当服务器响应的时候,一个回调函数会处理服务器响应。几个参数会传递给该函数供其使用。首先,也是最重要的,服务器返回的数据作为第一个参数传递。

我们可以格式化服务器以任意多种形式返回的数据。服务器端的脚本可以返回一个数值、一个单词、一段文本或者是一个完整的Web页面。在服务器发送很多信息的情况下(例如来自数据库的一组记录),服务器通常使用XML或JSON(参见11.3.6节的“高级用户提示:接收来自服务器的XML”部分了解关于XML的更多内容,参见11.4节了解关于JSON的介绍)。回调函数的第二个参数是表示响应状态的一个字符串。大多数时候,这个状态是“成功的”,意味着服务器已经成功地处理了请求并返回了数据。然而,有时候,一个请求不会成功,例如,请求的一个文件不存在,或者在服务器端程序中有一个错误。如果一个请求失败了,回调函数接收一个“错误”状态消息。

回调函数以某种方式处理信息,并且,大多数时候,会以某种方式更新Web页面,例如,使用来自服务器的结果替代一个提交的表单,或者直接在页面上显示一条“请求成功”的消息。使用4.7节介绍的html()和text()函数可以很容易地更新一个Web页面的内容。操作一个页面的DOM的其他方法在本书第4章中介绍。

要了解整个请求/响应的过程,看一下电影评级示例的基本过程(如图11-6所示)。访问者可以通过单击5个链接中的一个来给电影评级。每个链接表示一个不同的级别。当访问者单击一个链接,评级以及被评级的电影的ID都发送给一个服务器端程序,这给数据库添加了一个分级,然后给电影返回一个平均的评级。然后平均的评级显示在Web页面上。

11.3.5 处理来自服务器的数据 - 图1

图 11-6 在这个页面上,访问者单击一个链接来对电影评级(如上图所示)。通过添加Ajax,我们可以向服务器提交评级而不用离开页面。实际上,使用服务器的响应,我们可以更新页面的内容(如下图所示)

为了让这个页面在没有JavaScript的情况下工作,页面上的每个链接都指向可以处理访问者评级的一个动态服务器端页面。例如,5星的评级链接(如图11-6所示)可能是rate.php?rate=5&movie=123。处理评级的服务器端文件叫做rate.php,而查询字符串(?rate=5&movie=123)包含了提供给服务器的两段信息:一个评级(rate=5)和一个表示被评级电影的编号(movie=123)。可以使用JavaScript来“劫持”对这些链接的单击并将它们转换为Ajax来调用服务器:


1$('#message a').click(function(){

2 var href=$(this).attr('href');

3 var querystring=href.slice(href.indexOf('?')+1);

4$.get('rate.php',querystring, processResponse);

5 return false;//stop the link

6});


第1行选择包含在另一个ID为message的标签中的每个链接(<a>标签)(在这个例子中,用来对电影评级的每个链接都包含在ID为message的一个<div>中)。然后,对每一个链接的click事件应用一个函数。

第2行提取了链接的HREF属性,例如,href变量可能保存了rate.php?rate=5&movie=123这样的一个URL。第3行使用slice()方法(参见14.1.4节的介绍)来提取字符串的一部分,从而得到URL中的?后面的部分,而indexOf()方法(参见14.1.4节)用来确定?的位置(indexOf()方法使用这一信息来确定从哪里开始分割字符串)。

第4行是Ajax请求。这个请求使用GET方法发送给服务器文件rate.php,请求中包含了用于链接的查询字符串(如图11-7所示)。然后,结果将返回给回调函数processResponse。第5行只是阻止常规的链接行为,防止Web浏览器退出当前的页面并载入链接到的页面。

11.3.5 处理来自服务器的数据 - 图2

图 11-7 在这个图中,我们可以看到JavaScript和W e b服务器是如何交互的。g e t()函数向服务器发送信息,而回调函数processResponse()处理服务器所返回的信息

注意:如果需要回顾函数如何工作以及如何创建它们,请参见3.4节。

最后,应该创建回调函数。回调函数接收数据和带有响应状态的一个字符串(如果服务器返回信息,该字符串就是'success')。别忘了,回调函数的名字用于请求中(参见本节前面代码的第4行)。因此,在这个例子中,函数的名字是processResponse。处理服务器的响应的代码如下所示:


1 function processResponse(data){

2 var newHTML;

3 newHTML=’<h2>Your vote is counted</h2>’;

4 newHTML+=’<p>The average rating for this movie is';

5 newHTML+=data+’.</p>’;

6$('#message').html(newHTML);

7}


这个函数接收data参数,这是Web服务器返回的信息。这个data可能是纯文本、HTML、XML或JSON。第2行创建了一个新的变量,用来保存将要在页面中显示的HTML(例如,“Your vote is counted”)。在第3行和第4行,newHTML变量中将填充一些HTML,包括一个<h2>标签和一个<p>标签。服务器的响应在第5行之前不会派上用场,在第5行,来自服务器的响应(存储在data变量中)添加到了newHTML变量。在这个例子中,服务器返回了带有电影的平均星级的一个字符串,例如,'3 stars'。

提示:如果想要给站点添加一个星级评定系统,有一个不错的jQuery插件可以处理大部分的细节工作,可以在http://www.wbotelhos.com/raty/找到。

最后,第6行使用jQuery的html()函数(参见4.7节的介绍),使用新的HTML替换了ID为message的<div>的内容,从而修改了Web页面上的HTML。结果如图11-6的下图所示。

在这个例子中,回调函数定义于get()函数之外,然而,如果想要把所有的Ajax代码保留在一起,可以使用一个匿名函数(参见4.10.1节):


$.get('file.php',data, function(data, status){

//callback function programming goes here

});


例如,你可以使用一个匿名函数来重写本节评定电影星级代码的第4行,如下所示:


$.get('rate.php',querystring, function(data){

var newHTML;

newHTML=’<h2>Your vote is counted</h2>’;

newHTML+=’<p>The average rating for this movie is';

newHTML+=data+’.</p>’;

$('#message').html(newHTML);

});//end get