`

在请求和响应中使用 XML (转)

    博客分类:
  • xml
 
阅读更多
从客户机到服务器的 XML

我们来看看将 XML 作为从客户机向服务器发送数据的格式。我们首先讨论技术上的实现,然后花些时间分析什么时候适合什么时候不适合使用它。

发送名/值对

在您编写的 90% Web 应用程序中,最终都会使用名/值对发送到服务器。比方说,如果用户在网页表单中输入姓名和地址,可能希望数据采用下列形式:

firstName=Larry

lastName=Gullahorn

street=9018 Heatherhorn Drive

city=Rowlett

state=Texas

zipCode=75080



如果使用普通文本把这些数据发送到服务器,可以使用清单 1 所示的代码。类似于本系列第一期文章中使用的那个例子。请参阅参考资料。


清单 1. 使用普通文本发送名/值对



function callServer() {

  // Get the city and state from the Web form

  var firstName = document.getElementById("firstName").value;

  var lastName = document.getElementById("lastName").value;

  var street = document.getElementById("street").value;

  var city = document.getElementById("city").value;

  var state = document.getElementById("state").value;

  var zipCode = document.getElementById("zipCode").value;



  // Build the URL to connect to

  var url = "/scripts/saveAddress.php?firstName=" + escape(firstName) +

    "&lastName=" + escape(lastName) + "&street=" + escape(street) +

    "&city=" + escape(city) + "&state=" + escape(state) +

    "&zipCode=" + escape(zipCode);



  // Open a connection to the server

  xmlHttp.open("GET", url, true);



  // Set up a function for the server to run when it's done

  xmlHttp.onreadystatechange = confirmUpdate;



  // Send the request

  xmlHttp.send(null);

}



将名/值对转化成 XML

如果希望这样使用 XML 作为数据格式,首先要做的是找到一种基本 XML 格式来存储数据。显然,名/值对可以全部转化成 XML 元素,以其中的名称作为元素名,值作为元素的内容:

<firstName>Larry</firstName>

<lastName>Gullahorn</lastName>

<street>9018 Heatherhorn Drive</street>

<city>Rowlett</city>

<state>Texas</state>

<zipCode>75080</zipCode>



当然,XML 要求有一个根元素;如果使用文档片段(XML 文档的一部分)的话则需要一个封闭元素。因此可能需要将上述 XML 转化成下面的形式:

<address>

  <firstName>Larry</firstName>

  <lastName>Gullahorn</lastName>

  <street>9018 Heatherhorn Drive</street>

  <city>Rowlett</city>

  <state>Texas</state>

  <zipCode>75080</zipCode>

</address>



现在基本上可以准备在 Web 客户机上创建这种结构并发送到服务器了。

通信,口头上的

在网络上传输 XML 之前,需要保证服务器以及发送数据的脚本能够接受 XML。现在对很多人来说这么强调似乎有点多余,认为这是理所当然的,但是很多新手往往认为只要通过网络发送 XML,就能够被正确地接收和解释。

实际上,需要两个步骤来保证发送的 XML 的数据能够被正确地接收:

    保证向其发送 XML 的脚本能够接受 XML 数据格式。
    保证脚本认可发送数据所采用的特定 XML 格式和结构。

这两方面都可能要求您进行人际沟通,必须明确地告知对方!严格地说,如果确实需要发送 XML 数据,多数脚本作者都会帮助您,因此寻找能够接受 XML 的脚本应该不难。但是,仍然需要保证格式是脚本所希望的格式。比方说,假设服务器接受下列格式的数据:

<profile>

  <firstName>Larry</firstName>

  <lastName>Gullahorn</lastName>

  <street>9018 Heatherhorn Drive</street>

  <city>Rowlett</city>

  <state>Texas</state>

  <zip-code>75080</zip-code>

</profile>



看起来和上面的 XML 类似,只有两点不同:

    来自客户机的 XML 封装在 address 元素,但是服务器要求数据封装在 profile 元素中。
    来自客户机的 XML 使用了 zipCode 元素,而服务器希望邮政编码放在 zip-code 元素中。

从大的层面上来说,这些小问题仅仅是服务器接收和处理数据的区别,但是服务器会彻底失败,在网页上(可能向其用户)显示意义含糊的错误消息。因此必 须明确服务器的期望的格式,并把要发送的数据塞进那种格式。然后,只有在这时才会涉及到从客户机向服务器发送 XML 数据的真正的技术问题。

向服务器发送 XML

当向服务器发送 XML 的时候,更多的代码用于获取数据和包装成 XML,而不是真正的传输数据。实际上,只要准备好发送到服务器的 XML 字符串,发送工作就和普通文本一样了,如清单 2 所示。


清单 2. 用 XML 发送名/值对



function callServer() {

  // Get the city and state from the Web form

  var firstName = document.getElementById("firstName").value;

  var lastName = document.getElementById("lastName").value;

  var street = document.getElementById("street").value;

  var city = document.getElementById("city").value;

  var state = document.getElementById("state").value;

  var zipCode = document.getElementById("zipCode").value;



  var xmlString = "<profile>" +

    "  <firstName>" + escape(firstName) + "</firstName>" +

    "  <lastName>" + escape(lastName) + "</lastName>" +

    "  <street>" + escape(street) + "</street>" +

    "  <city>" + escape(city) + "</city>" +

    "  <state>" + escape(state) + "</state>" +

    "  <zip-code>" + escape(zipCode) + "</zip-code>" +

    "</profile>";



  // Build the URL to connect to

  var url = "/scripts/saveAddress.php";



  // Open a connection to the server

  xmlHttp.open("POST", url, true);



  // Tell the server you're sending it XML

  xmlHttp.setRequestHeader("Content-Type", "text/xml");



  // Set up a function for the server to run when it's done

  xmlHttp.onreadystatechange = confirmUpdate;



  // Send the request

  xmlHttp.send(xmlString);

}



大部分代码都很简单,只有少数地方值得提一下。首先,请求中的数据必须手工格式化为 XML。阅读了三篇关于使用文档对象类型的文章之后,再来讨论它是不是很简单了?虽然不禁止在 JavaScript 中使用 DOM 创建 XML 文档,但是在通过 GET 或 POST 请求发送到网络上之前必须将 DOM 对象转化成文本。因此使用常规字符串操作来格式化数据更简单一些。当然,这样很容易出现错误和误输入,因此在编写处理 XML 的代码时必须非常小心。

建立 XML 之后,按照和发送文本基本相同的方式打开连接。对于 XML 最好使用 POST 请求,因为有些浏览器限制了 GET 请求字符串的长度,而 XML 可能很长,可以看到清单 2 中把 GET 改成了 POST 方法。此外,XML 通过 send() 方法发送,而不是附加在请求 URL 最后的参数。这些都是非常细微的区别,很容易修改。

但是必须编写一行新的代码:

xmlHttp.setRequestHeader("Content-Type", "text/xml");



看起来很难理解,它只不过是告诉服务器要发送的是 XML 而不是一般的名/值对。无论哪种情况,发送的数据都是文本,但这里使用 text/xml 或者 XML 作为普通文本发送。如果使用名/值对,对应的行应该是:

xmlHttp.setRequestHeader("Content-Type", "text/plain");



如果忘记告诉服务器发送的是 XML,就会出现问题,因此不要忘掉这一步骤。

完成这些之后,剩下的就是调用 send() 并传入 XML 字符串了。服务器将收到您的 XML 请求,并(假设已经做好了准备工作)接受 XML,解释它,然后返回响应。实际上要做的只有这么多 —— XML 请求只需要稍微修改代码。






回页首



发送 XML:好还是不好?

在结束 XML 响应的 XML 请求(以及本文)之前,我们花点时间讨论一下在请求中使用 XML 的感受。前面已经提到,就传输而言 XML 完全不是最快的方式,但是还有更多因素要考虑。

构造 XML 不是简单的事情

首先必须认识到,对于请求来说构造 XML 不是简单的事。如清单 2 所示,数据很快就会和 XML 语义纠缠在一起:

var xmlString = "<profile>" +

  "  <firstName>" + escape(firstName) + "</firstName>" +

  "  <lastName>" + escape(lastName) + "</lastName>" +

  "  <street>" + escape(street) + "</street>" +

  "  <city>" + escape(city) + "</city>" +

  "  <state>" + escape(state) + "</state>" +

  "  <zip-code>" + escape(zipCode) + "</zip-code>" +

  "</profile>";



似乎还不坏,但是要知道这是只有六个字段的 XML 片段。开发的多数 Web 表单都有十到十五个字段,虽然不一定所有的请求都使用 Ajax,但是应该考虑这种情况。至少要花和实际数据同样多的时间来处理尖括号和标签名称,有可能使本来很少的输入变得非常大。

这里的另一个问题前面已经提到,即必须手工创建 XML。使用 DOM 不是一种好的选择,因为没有简单易行的办法将 DOM 对象转化成在请求中发送的字符串。因此像这样使用字符串处理是最好的办法,不过也是一种维护起来最困难和新开发人员最难理解的方法。在这个例子中,所有 XML 都在一行中构造完成,如果分为多步只会更加混乱。

XML 没有为请求增加任何东西

除了复杂性的问题之外,和普通文本以及名/值对相比,在请求中使用 XML 实际上没有多少好处(如果有的话)。要注意,本文坚持使用前面用名/值对发送的同一些数据(请参阅清单 1)来用 XML 发送。我没有提什么数据能用 XML 但是不能用普通文本发送,这是因为实际上没有任何东西可用 XML 而不能用普通文本发送。

事实上这就是 XML 和请求的底线:不是一定非要这么做不可。在本系列的下一期文章中将看到服务器可以使用 XML 实现普通文本很难做到的一些事情,但请求不属于这种情况。因此除非和只接受 XML 的脚本(确实存在这样的脚本)打交道,在请求中最好使用普通文本。







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

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

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



给我一点空间!

在绝大多数 HTTP 请求中,转义序列 %20 用于表示一个空格,文本 “Live Together, Die Alone” 将以 Live%20Together,%20Die%20Alone 的形式通过 HTTP 发送。

对于您来说,这就意味没有任何简单的方法在响应中使用纯文本、使客户机以一种标准的方法获取并解释响应,至少在响应包含多个值时是如此。假设您的服务器只是要发回数字 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);

    }

  }

}





前文回顾

为避免出现大量重复的代码,本系列这些后续的文章只给出与所探讨的主题相关的那部分代码。因此,清单 4 仅仅展示了 Ajax 客户机代码中的回调方法。如果您对于此方法在更大的异步应用程序环境中的位置尚不清楚,应回顾本系列的前几篇文章,那些文章介绍了 Ajax 应用程序的基础知识。参考资料 中列出了前几篇文章的链接。

在这个代码片段中,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 用在了最适合它的地方,避免了在不适合的地方使用它(比如说向服务器发送请求时)。
分享到:
评论

相关推荐

    Ajax\掌握 Ajax第 7 部分-在请求和响应中使用 XML

    Ajax\掌握 Ajax第 7 部分-在请求和响应中使用 XML

    掌握 Ajax第 8 部分-在请求和响应中使用 XML.pdf

    掌握 Ajax第 8 部分-在请求和响应中使用 XML.pdf

    掌握Ajax系列7:在请求和响应中使用XML(上)

    在本系列前面的文章中,我们使用普通文本和名/值参数发送数据,但XML也是一种可行的格式。本文将介绍如何来这样做。但最重要的是,我将讨论为何可以使用 XML作为请求格式,以及为何在多数情况下不应该使用它。

    Ajax3_在请求和响应中使用XML

    看起来它似乎是为通过HTTP请求发送XML或者以某种XML格式发出HTTP请求而设计的,但实际上它要做的只不过是为客户机代码(在网页中通常是JavaScript)提供一种发送HTTP请求的方式,并不要求必须使用XML请求或响应。

    掌握Ajax系列8:在请求和响应中使用XML(下)

    在Ajax应用程序中,使用XML作为发送数据的格式的理由很少,但使服务器向 客户机回发XML的理由很多。因此,您在上一篇文章中学到的关于XML的知识最终将在这篇文章中体现出某些价值。这篇文章主要探讨在大多数情况下...

    掌握 Ajax 在请求和响应中使用 XML

    无论考虑转向 XHTML 的网页设计人员、使用 JavaScript 的 Web 程序员、使用部署描述文件和数据绑定的服务器端程序员,还是研究基于 XML 的数据库的后端开发人员,都在使用这种可扩展标记语言。因此,XML 被认为是 ...

    发送Post请求,内容格式为xml,并获取响应内容

    发送Post请求,内容格式为xml,并获取响应内容

    掌握Ajax,第7部分:在请求和响应中使用XML

    在本文中,您将看到服务器如何在请求响应中发送XML。 现在如果不使用XML就不能进行任何有意义的编程。无论考虑转向XHTML的网页设计人员、使用JavaScript的Web程序员、使用部署描述文件和数据绑定的服务器端程序员,...

    Spring Boot中扩展XML请求与响应的支持详解

    主要给大家介绍了关于Spring Boot中扩展XML请求与响应的支持的相关资料,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    请求响应案例资源xml

    配合JavaWeb开发 —— 请求响应案例分析所需资源

    AJAX 学习资料WORD文档

    第 1 部分: Ajax 入门...第 7 部分: 在请求和响应中使用 XML 80 第 8 部分: 在请求和响应中使用 XML 87 第 9 部分: Web 2.0 用户界面技术 95 第 10 部分: 使用 JSON 进行数据传输 100 第 11 部分: 服务器端的 JSON 105

    Servlet请求和响应的资料,帮助初学者掌握Servlet的请求和响应

    3. web容器通过请求的URL来选择需要用哪个Servlet来处理请求(这个就是web.xml中配置的或者 @webServlet注解的作用了) 4. Servlet根据请求对象(HttpServletRequest)来决定做什么样的处理,然后通过响应对象 ...

    使用Servlet技术响应用户请求

    要在Web应用程序中使用Servlet,您需要将其部署到Web服务器上。 Web服务器通常支持Java Servlet规范,并提供一个Servlet容器,例如Tomcat或Jetty。您可以将编译后的Servlet类文件(.class文件)部署到Servlet容器中...

    AJax详解.chm

    第 7 部分: 在请求和响应中使用 XML 第 8 部分:在请求和响应中使用 XML 第 9 部分: 使用 Google Ajax Search API 第 10 部分: 使用 JSON 进行数据传输 第 11 部分:将 Ajax 带入 Eclipse 的 Ajax Toolkit ...

    掌握Ajax 学习资料pdf

    掌握 Ajax第 1 部分-Ajax 简介 掌握 Ajax第 2 部分-使用 JavaScript 和 Ajax 发出...掌握 Ajax第 7 部分-在请求和响应中使用 XML 掌握 Ajax第 10 部分--使用 JSON 进行数据传输 掌握 Ajax第 11 部分--服务器端的 JSON

    Ajax详解

    内容简要给大家说明一下:Ajax简介、使用Javascript和Ajax发出异步请求、Ajax中的高级请求响应、利用Dom进行Web响应、操作dom、建立基于Dom的Web应用程序、在请求和响应中使用XML、使用Json进行数据传输、...

    ArcIMS地图配置文件,地图服务,请求和响应之间的关系

    与空间服务器之间的所有的交流都是使用ArcXML,图1显示了空间服务器和地图配置文件,地图服务,请求和响应之间的相互关系。图表中的数字反映了与空间服务器交流的不同步骤。 第1步,使用Author工具,文本编辑...

    掌握Ajaxchm格式

    资源名称:掌握Ajax chm格式内容简介:Ajax新手的入门手册,全部是基础简单的理论,深入学习AJAX的基础,整个教程总七个... 7、在请求和响应中使用XML;资源 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。

    Axis2的OMElement SOAP XML报文节点首字母小写转大写(注意,是节点,不是节点元素的值) java

    Axis2的OMElement SOAP XML报文节点首字母小写转大写(注意,是节点,不是节点元素的值) java

Global site tag (gtag.js) - Google Analytics