向客户机返回XML响应

日期: 2008-07-13 作者:Brett McLaughlin 来源:TechTarget中国

  在本系列的上一篇文章 中,您看到了Ajax应用程序如何以XML格式化发往服务器的请求。还了解了为什么这在大多数情况下并不是一个好主意。这篇文章主要探讨在大多数情况下确实是好主意的一种做法:向客户机返回XML响应。


  我其实并不喜欢写那种主要告诉您什么不应该做的文章。很多时候,那都会是一篇非常愚蠢的文章。我要在前半篇文章中解释某些东西,然后在后半篇文章中说明使用您刚刚才学会的那种技术是一个多么糟糕的主意。在很大程度上,上一期文章正是这样一种情况(如果您错过了那一期文章,请查看参考资料中的链接),那篇文章教您如何将XML作为Ajax应用程序的请求数据格式使用。


  但愿这篇文章能够弥补您花费在学习XML请求上的时间。在Ajax应用程序中,使用XML作为发送数据的格式的理由很少,但使服务器向客户机回发XML的理由很多。因此,您在上一篇文章中学到的关于XML的知识最终将在这篇文章中体现出某些价值。


  服务器(有时)不能响应太多的请求


  在深入钻研从服务器获取XML响应的技术之前,您需要理解,为什么说使服务器发送XML来响应请求是一个好主意(以及这与客户机发送XML请求不同的原因所在)。


  客户机以名称/值对发送请求


  回忆一下上一篇文章,就会知道,在大多数情况下,客户机不需要使用XML,因为他们会使用名称/值对发送请求。因此,您可能会发送一个这样的名称:name=jennifer。只需简单地在连续的名称/值对之间添加一个“与”符号(&),即可将其放在一起,就像这样:name=jennifer&job=president。使用简单的文本和这些名称值对,客户机即可轻松向服务器请求多个值。很少需要用到XML提供的额外结构(及其带来的额外开销)。


  实际上,需要向服务器发送XML的所有理由都差不多可以归入以下两个基本的类别中:


  ·服务器仅接受XML请求。在这类情况下,您别无选择。上一期文章中介绍的基础知识应已使您掌握了发送此类请求所必需的工具。
  ·您正在调用一个仅接受XML或SOAP请求的远程API。这实际上就是上一种情况的特例,但值得单独拿出来提一下。如果您希望在一个异步请求中使用来自Google或Amazon的API,就会有一些特殊的考虑事项。在下一期的文章中,我将介绍这些考虑事项,还会给出一些向API发送此类请求的示例。


  服务器无法(以一种标准方式)发送名称/值对


  在您发送名称/值对时,Web浏览器会发送请求,平台会响应该请求,并承载一个服务器程序,配合它将那些名称/值对转换成服务器程序可以轻松处理的数据。实际上,每一种服务器端技术——从Java? servlet到PHP、再到Perl、Ruby on Rails——都允许您调用多种方法来根据名称获取值。因此,获取name属性只是小事一桩。


  这种情况并不会将我们引向另外一个方向。如果服务器使用字符串name=jennifer&job=president应答一个应用程序,客户机没有任何标准化的简便方法来将每个对拆分成名称和值。您必须手动解析所返回的数据。如果服务器返回一个由名称/值对构成的响应,这样的响应的解释难度与使用分号、竖线或其他任何非标准格式化字符相同。


  对于您来说,这就意味没有任何简单的方法在响应中使用纯文本、使客户机以一种标准的方法获取并解释响应,至少在响应包含多个值时是如此。假设您的服务器只是要发回数字42,那么纯文本是很好的选择。但如果服务器要一次性发回电视剧Lost,Alias和Six Degrees的近期收视率又该怎么办呢?尽管可以选择许多种方法来使用纯文本发送这一响应(清单1给出了一些示例),但没有一种是不需客户机进行某些处理的极其简单的方法,也没有一种是标准化的方法。


  清单1. 收视率的服务器响应(不同版本)


  show=Alias&ratings=6.5|show=Lost&ratings=14.2|show=Six%20Degrees&ratings=9.1


  Alias=6.5&Lost=14.2&Six%20Degrees=9.1


  Alias|6.5|Lost|14.2|Six%20Degrees|9.1
 
  尽管不难找到拆分这些响应字符串的方法,但客户机将不得不根据分号、等号、竖线和与符号解析并拆分这些字符串。这不是编写使其他开发人员能够轻松理解和维护的健壮代码的方法。


  进入XML


  意识到没有任何标准的方法可以使服务器使用名称/值对响应客户机之后,使用XML的原因也就显而易见了。向客户机发送数据时,名称/值对是非常好的选择,因为服务器和服务器端语言可以轻松解释名称/值对;向客户机返回数据时使用XML也是如此。在本系列前几期的文章中,您已经看到了利用DOM来解析XML,在后续的文章中,还会看到JSON怎样提供了解析XML的另一种选择。在所有这一切之上,您可以将XML作为纯文本处理,并以这种方式获取其值。因此,有几种方法可从服务器获得XML响应,并使用较为标准的代码提取数据,在客户机中使用这些数据。


  还有一个额外的好处,XML非常易于理解。比如说,大多数编写程序的人都能理解 清单2中的数据。


  清单2. 收视率的服务器响应(XML格式)


  <ratings>
   <show>
    <title>Alias</title>
    <rating>6.5</rating>
   </show>
   <show>
    <title>Lost</title>
    <rating>14.2</rating>
   </show>
   <show>
    <title>Six Degrees</title>
    <rating>9.1</rating>
   </show>
  </ratings>
 
  在特定分号或撇号的含义方面,清单2中的代码没有任何隐晦之处。


  从服务器接收XML


  由于本系列的重点在于Ajax应用模式的客户端,因此我不会深入探讨关于服务器端程序如何才能生成XML响应的细枝末节。但在您的客户机接收XML时,您需要了解一些特殊的考虑事项。


  首先,您可使用两种基本的方式处理一个来自服务器的XML响应:


  ·作为碰巧被格式化为XML的纯文本
  ·作为一个XML文档,由一个DOM Document对象表示。


  其次,举例来说,假设有一个来自服务器的简单XML响应。清单3展示了与上面介绍的内容相同的收视率程序清单(实际上,是与清单2相同的XML,在这里再次给出只是为了使您便于查看)。我将在这部分的讨论中使用这段样本XML。


  清单3. XML格式的收视率示例


  <ratings>
   <show>
    <title>Alias</title>
    <rating>6.5</rating>
   </show>
   <show>
    <title>Lost</title>
    <rating>14.2</rating>
   </show>
   <show>
    <title>Six Degrees</title>
    <rating>9.1</rating>
   </show>
  </ratings>
 
  将XML作为纯文本处理


  处理XML的最简单的选择(至少就学习新的编程技术而言),就是用与处理服务器返回的其他文本片段相同的方法来处理它。换言之,基本上就是忽略数据格式,只关注服务器的响应。


  在这种情况下,您要使用请求对象的responseText属性,就像在服务器向您发送非XML响应时一样(参见清单4)。


  清单4. 将XML作为普通服务器响应处理


  function updatePage() {
    if (request.readyState == 4) {
      if (request.status == 200) {
        var response = request.responseText;


        // response has the XML response from the server
        alert(response);
      }
    }
  }
 
  在这个代码片段中,updatePage()是回调方法,request是XMLHttpRequest对象。最终,您将得到把所有一切串联在一起的XML响应,位于response变量之中。如果输出此变量,您会得到类似于清单5的结果。(请注意,清单5中的代码在正常情况下应该是连续的一个代码行。这里采用多行形式是为了显示正常。)


  清单5. response变量的值


  <ratings><show><title>Alias</title><rating>6.5</rating>
  </show><show><title>Lost</title><rating>14.2</rating></show><show>
  <title>Six Degrees</title><rating>9.1</rating></show></ratings>
 
  这里,要注意的最重要的地方就是XML是作为整体运行的。在大多数情况下,服务器不会使用空格和回车来格式化XML,而是将一切串联在一起,就像您在清单5中看到的那样。当然,您的应用程序不会过于在意空格,所以这算不上什么问题,但确实会使代码阅读起来较为困难。


  在这里,您可以使用JavaScript split函数来拆分此数据,并通过基本的字符串操作来获得元素的名称和值。毫无疑问,这是个令人头疼的过程,它无视于您花费了大量时间来阅读前几期文章中DOM(Document Object Model)相关内容这一事实。因此,我要强调,您应该牢记:利用responseText,可以轻松使用和输出服务器的XML响应,但我不会为您展示太多的代码,在能够使用DOM时,您不应选择这种方法来获得XML数据,下面您会看到这一点。


  将XML当成XML


  尽管可以将服务器的XML格式的响应视同为其他任何文本响应来处理,但这样做没有很好的理由。首先,如果您一直忠实地阅读这个系列,那么您已经学会了如何使用DOM这种对JavaScript友好的API来操纵XML。还有更好的事情,JavaScript和XMLHttpRequest对象提供了一个属性,它能完美地获取服务器的XML响应,并且是以DOM Document对象的形式来获取它。


  清单6给出了一个实例。这段代码与清单4类似,但没有使用responseText属性,回调函数使用的是responseXML属性。该属性在XMLHttpRequest上可用,它以DOM文档的格式返回服务器的响应。


  清单6. 将XML当作XML


  function updatePage() {
    if (request.readyState == 4) {
      if (request.status == 200) {
        var xmlDoc = request.responseXML;


        // work with xmlDoc using the DOM
      }
    }
  }
 
  现在您有了一个DOM Document,可以像处理其他任何XML一样处理它。例如,随后可能要获取所有show元素,如清单7所示。


  清单7. 获取所有show元素


  function updatePage() {
    if (request.readyState == 4) {
      if (request.status == 200) {
        var xmlDoc = request.responseXML;


        var showElements = xmlDoc.getElementsByTagName(“show”);
      }
    }
  }
 
  如果您熟悉DOM,从这儿开始,看起来就应该有几分熟悉了。您可以使用您所了解的全部DOM方法,轻松操纵从服务器处接收到的XML。


  当然,您也可以混用普通的JavaScript代码。例如,可以遍历所有show元素,如 清单8所示。


  清单8. 遍历所有show元素


  function updatePage() {
    if (request.readyState == 4) {
      if (request.status == 200) {
        var xmlDoc = request.responseXML;


        var showElements = xmlDoc.getElementsByTagName(“show”);
        for (var x=0; x<showElements.length; x++) {
          // We know that the first child of show is title, and the second is rating
          var title = showElements[x].childNodes[0].value;
          var rating = showElements[x].childNodes[1].value;


          // Now do whatever you want with the show title and ratings
        }
      }
    }
  }
 
  通过这段非常简单的代码,您正是将XML响应作为XML而不是无格式的纯文本进行了处理,还使用了一点DOM和简单的JavaScript来处理服务器响应。更重要的是,您使用了标准化的格式——XML,而不是以逗号分隔的值或以竖线分隔的名称/值对。换句话说,您将XML用在了最适合它的地方,避免了在不适合的地方使用它(比如说向服务器发送请求时)。


  服务器端的XML:一个简单的示例


  我不会谈太多有关如何在服务器上生成XML的内容,但花点儿时间看一个简单的示例是值得的,我没有给出过多的注释,以便您自行思考如何应对这样的场景。清单9展示了一个简单的PHP脚本,假设有一个异步客户机发出了请求,该脚本将输出XML来应答此请求。


  这是一种强力(brute force)的方法,PHP脚本实际上是手动生成XML输出。您可以找到许多工具包和API,用于PHP和其他众多允许您生成XML响应的服务器端语言。无论您的情况如何,这都至少能让您了解生成XML并以之应答请求的服务器端脚本看上去是什么样子。


  清单9. 返回XML的PHP脚本


  <?php


  // Connect to a MySQL database
  $conn = @mysql_connect(“mysql.myhost.com”, “username”, “secret-password”);
if (!conn)
    die(“Error connecting to database: ” . mysql_error());


  if (!mysql_select_db(“television”, $conn))
    die(“Error selecting TV database: ” . mysql_error());


  // Get ratings for all TV shows in database
  $select = ’select title, rating’;
  $from   = ’  FROM ratings’;
  $queryResult = @mysql_query($select . $from);
  if (!$queryResult)
    die(“Error retrieving ratings for TV shows.’);


  // Let the client know we’re sending back XML
  header(“Content-Type: text/xml”);
  echo “<?xml version=”1.0″ encoding=”utf-8″?>”;
  echo “<ratings>”;


  while ($row = mysql_fetch_array($queryResult)) {
    $title = $row[’title’];
    $rating = $row[’rating’];


    echo “<show>
    echo “<title>” . $title . “</title>”;
    echo “<rating>” . $rating . “</rating>”;
    echo “</show>”;
  }


  echo “</ratings>”;


  mysql_close($conn);


  ?>
 
  您应能够使用您偏爱的服务器端语言以类似的方式输出XML。IBM developerWorks上有许多文章可以帮助您了解如何使用您喜爱的服务器端语言生成XML文档(相关链接请参见参考资料)。


  解释XML的其他可选方法


  除将XML作为无格式文本处理或使用DOM处理之外,还有一种非常流行的选择很重要,值得一提。那就是JSON(JavaScript Object Notation),这是一种绑定在JavaScript内的自由文本格式。这篇文章中没有足够的空间介绍JSON,在后续文章中将探讨相关内容;只要提起XML和Ajax应用程序,您就很可能会听到有人谈论JSON,因此现在我将告诉您,您的工作伙伴们在谈论的究竟是什么。


  大体上,可以用JSON做的事,用DOM都可以完成,反之亦然;选择主要取决于偏好,当然也要为特定的应用程序选择正确的方法。就现在而言,您应坚持使用DOM,在接收服务器响应的过程中熟悉DOM。我将占用几期文章的篇幅、用大量的时间去探讨JSON,之后您就可以随意选择在下一个应用程序中使用那种技术了。请继续关注本系列:后续文章中将介绍关于XML的更多内容。


  结束语


  从本系列上一篇文章开篇起,我几乎一直在谈论XML,但对于XML在Ajax应用模式中的贡献而言,我触及的依然仅仅是表面。在下一期文章中,您将更详细地了解那些您将希望发送XML的特殊场景(还会看到那些需要接收XML的场景)。具体来说,您会在Ajax交互的角度上观察Web服务——包括专有Web服务和Google那样的API。


  简而言之,最重要的任务就是思考对于您的应用程序,XML在什么时候才是有意义的。在很多情况下,如果您的应用程序工作良好,XML只不过是又一个让您头疼的技术时髦词汇,您应该克制住仅仅为了宣称应用程序中有XML而尝试它的冲动。


  如果您处于这样一个环境中:服务器向您发送的数据非常有限,或者采用的是奇怪的逗号分隔、竖线分隔的格式,那么XML可能会给您带来真正的收益。考虑处理或更改您的服务器端组件,以使它们用更为标准化的方式——使用XML——来返回响应,而不是使用那些健壮性比XML差的专用格式。


  最重要的是,要认识到,您对Ajax相关技术了解的越多,就必须越谨慎地制定决策。编写那些Web 2.0应用程序确实很有趣(在后续文章中,您将重返用户界面,看看可以在这里做些什么很酷的东西),但要注意,确保您不是为了向朋友炫耀而在一个可以正常工作的Web页面上滥用这些技术。我确信,您能编写出优秀的应用程序,那么就动手去做吧。完成后,再回来阅读下一期文章,学习关于XML的更多知识。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐

  • 云计算究竟是否威胁到了硬件业?

    虚拟化和云计算是目前存储、服务器和网络行业的关键的方面。许多企业正在提供虚拟化的环境或者鼓励人们采用云计算以便 […]

  • 八个超实用的jQuery技巧攻略

    jQuery是JavaScript最好的库之一,主要用于制作动画、事件处理,支持Ajax及HTML脚本客户端。文中分享了8个超实用的jQuery代码技巧攻略,希望你会喜欢。

  • BEST:SOAP/XML和REST的替代方案

    虽然拥有大量的机架服务器,以及大量软件开发人员的组织,基于web和集成服务的SOAP和REST很适合他们,但也会出现问题。

  • Spring 烂!差!

    有些人可能对Spring的第一印象不太好,它真的很烂,很差吗,也许这只是你的一种偏见,它也有是自己的优点的。