使用 XMLHTTP 的动态页更新

文章翻译 文章翻译
文章编号: 893659 - 查看本文应用于的产品
ASP.NET 支持语音列

使用 XMLHTTP 的动态页更新

要自定义此列设置为您的需要,我们想要邀请您提交您的想法有关您和您想要查看的问题感兴趣的主题在将来解决知识文库文章和 Support Voice 专栏。您可以提交您的意见和反馈使用 诚征意见 表单。也是一个链接到该窗体,在此列的底部。
展开全部 | 关闭全部

本文内容

简介

我最喜欢的方法来研究 Web 应用程序的可用性之一是监视 Web 站点中导航的妻子。她可以使她围绕互联网的方法很有效,但她知道在底层甚技术方面 (什么她调用"乏味的资料"),使其所有工作。

在最近的晚上,我在注视我妻子细读电子商务应用程序从一个大男孩。她已深入到每个送纸从以前所做的选择使用多个下拉列表,其中列出的产品。她单击每个下拉列表中的项时,在页面发送到下拉列表的下一步中获取数据。经验是她的令人沮丧,因为她留下的印象是它需要较长的时间,由于回。

她遇到的挫折级别可能有被轻松地缓解由应用程序开发人员如果它们只用于 XMLHTTP 检索数据,而不要回。这是本月专栏的内容。我将向您展示如何使用 XMLHTTP 来自 Microsoft ASP.NET Web 服务的数据更新 Web 页的一部分,而不执行回发。这将真正的酷!请相信我。

一般概述

XMLHTTP 的工作原理是从客户端向 Web 服务器发送请求和返回的 XML 数据岛。根据接收到的 xml 结构,可以使用 XSLT 或 XML DOM 对其进行操作,并绑定到该数据的页面的某些部分。这是一种非常强大的技术。

注意Microsoft 不提供 Web 服务行为的 Internet Explorer,快速而轻松地使对 ASP.NET Web 服务的异步调用。但是,不支持这种行为并不是以异步方式更新页面的最佳办法。您应改用 XMLHTTP!

在示例中我将通过工作在本专栏中,我将三个对 XMLHTTP 通过 ASP.NET Web 服务的 Web 服务调用。Web 服务将查询在本地 SQL Server 上的罗斯文数据库,将返回到客户端的 XML diffgram 形式的数据集。我将使用 XML DOM 来分析该 XML 数据和动态地更新我的页面的某些部分。所有这些会在不回发的情况下进行操作。

Web 服务

我将使用的 Web 服务名为 DynaProducts。它是一个基本的 ASP.NET Web 服务,在 C# 中编写的并包含下列三种方法。
  • GetCategories – 返回包含类别表中的所有类别的数据集。
  • GetProducts – 返回包含所有类别的产品,它们传递给该方法的数据集。
  • GetProductDetails – 返回的数据集,其中包含有关该产品的产品 Id 传递给该方法的详细信息。

HTML 页

关于此示例可能会删除您的第一件事是我正在更新通过 ASP.NET Web 服务的页面不是一个 ASP.NET 页。它是只是一个普通的 HTML 页。但是,我已将大量的客户端 JavaScript 添加到页中,并且它是 Web 服务调用该脚本。

我们看一下第一个代码段的代码从 HTML 页。
var objHttp;
var objXmlDoc;

function getDataFromWS(methodName, dataSetName, wsParamValue, wsParamName)
{

    // create the XML object
    objXmlDoc = new ActiveXObject("Msxml2.DOMDocument");

    if (objXmlDoc == null)
    {
        alert("Unable to create DOM document!");
        
    } else {

	    // create an XmlHttp instance
	    objHttp = new ActiveXObject("Microsoft.XMLHTTP");
	
	
	    // Create the SOAP Envelope
	    strEnvelope = "<soap:Envelope xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
	
	            " xsd=\"http://www.w3.org/2001/XMLSchema\"" +
	
	            " soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
	
	            "  <soap:Body>" +
	
	            "    <" + methodName + " xmlns=\"http://jimcoaddins.com/DynaProducts\">" +
	
	            "    </" + methodName + ">" +
	
	            "  </soap:Body>" +
	
	            "</soap:Envelope>";
	
	
	    // Set up the post
	    objHttp.onreadystatechange = function(){
	
	        // a readyState of 4 means we're ready to use the data returned by XMLHTTP
	        if (objHttp.readyState == 4)
	        {
	
	            // get the return envelope
	            var szResponse = objHttp.responseText;
							
	            // load the return into an XML data island
	            objXmlDoc.loadXML(szResponse);
	
	            if (objXmlDoc.parseError.errorCode != 0) {
	                var xmlErr = objXmlDoc.parseError;
	                alert("You have error " + xmlErr.reason);
	            } else {
	
	                switch(dataSetName)
	                {
	                    case "CategoriesDS":
	                        processCategory();
	                        break;
	
	                    case "ProductsDS":
	                        processProducts();
	                        break;
	
	                    case "ProductDetailDS":
	                        processProductDetails();
	                        break;
	
	                }
	            }
	
	        }
	     }
	
	    var szUrl;
	    szUrl = "http://dadatop/wsXmlHttp/DynaProducts.asmx/" + methodName;
	
	    if (wsParamValue != null)
	    {
	
	        szUrl += "?" + wsParamName + "=" + wsParamValue;
	    }
	
	    // send the POST to the Web service
	    objHttp.open("POST", szUrl, true);
	    objHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	    objHttp.send(strEnvelope);
	  }
}
这是最大的页上,从代码段,我想转悬停在其上详细,这样您就会明白这怎么回事。

在此脚本块的顶部,我创建了两个变量: objHttpobjXmlDoc。这些都是我使用我 XMLHTTP 对象和 XML DOM 对象的变量。紧接的是getDataFromWS函数的函数定义。这是负责发出 Web 服务客户端调用的函数。它将采取以下四个参数,其中两个是可选的:
  • 方法名称--可以使用调用 Web 服务方法的名称。
  • 数据集名称– 由 Web 服务返回的数据集的名称。
  • wsParamValue --如果适用) 传递到 Web 服务的参数的值。(可选)
  • wsParamName --如果适用) 传递到 Web 服务的参数的名称。(可选)
让我们将getDataFromWS函数拆成零件,并讨论每个。以下是第一段:
// create the XML object
    objXmlDoc = new ActiveXObject("Msxml2.DOMDocument");

    if (objXmlDoc == null)
    {
    		alert("Unable to create DOM document!");

    } else {

		// create an XMLHTTP instance
		objHttp = new ActiveXObject("Microsoft.XMLHTTP");
下面的代码块创建 XMLHTTP 对象和 XML 文档的对象。接下来,我开始创建 SOAP 信封。
// Create the SOAP Envelope
strEnvelope = "<soap:Envelope xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
	
          " xsd=\"http://www.w3.org/2001/XMLSchema\"" +
	
          " soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
	
          "  <soap:Body>" +
	
          "    <" + methodName + " xmlns=\"http://jimcoaddins.com/DynaProducts\">" +
	
          "    </" + methodName + ">" +
	
          "  </soap:Body>" +
	
          "</soap:Envelope>";
在此代码中,我正在给一个字符串变量分配的 SOAP 信封,以便我可以将它传递给 Web 服务。它是很容易了解如何设置您的 Web 服务的 SOAP 信封的格式。只需浏览到该 Web 服务,然后单击以查看有关该方法的 SOAP 信封的方法之一。例如,下面是我看到的内容浏览这篇文章 wsXMLHTTP 中创建的 Web 服务的GetCategories方法时:

收起这个图片展开这个图片
envelope.png


ASP.NET 会告诉您如何 SOAP 信封也应为 HTTP POST 和 HTTP GET 设置格式。在这篇文章中介绍的示例中,我将使用 HTTP POST。

因此到目前为止顺利。现在让我们看一下代码的下一节。
// Set up the post
objHttp.onreadystatechange = function(){
	
// a readyState of 4	means we're ready to use the	data returned by	XMLHTTP
	if (objHttp.readyState == 4)
	{
	
		// get	the return envelope
		   var	szResponse	= objHttp.responseText;
	
		   // load	the return into an XML data island
		   objXmlDoc.loadXML(szResponse);
	
		   if (objXmlDoc.parseError.errorCode != 0) {
			var xmlErr =	objXmlDoc.parseError;
				 alert("You have error " + xmlErr.reason);
	}
	else	
	{

		switch(dataSetName)
				{
					case "CategoriesDS":
						processCategory();
						break;
					case "ProductsDS":
						processProducts();
						break;
					case "ProductDetailDS":
					processProductDetails();
						break;

				}
			}
当通过 XMLHTTP 请求时,XMLHTTP 对象将使用readyState属性来跟踪请求的状态。已从 Web 服务收到的所有数据, readyState属性都更改为的值为4。XMLHTTP 对象的onreadystatechange属性允许您设置readyState属性发生更改时将调用的回调函数。请确保已完整地接收的数据,可以防止对该数据执行操作之前我已准备好。

一旦收到的所有的数据,我创建的 XML 数据岛与响应通过使用responseText属性。您可能知道,来自 Web 服务的回应是以 XML 格式。在这种情况下,我正在返回 Microsoft ADO.NET 数据集。

此代码块的下一节将使用 switch 语句来调用适当的函数基于从 Web 服务返回的数据集的名称。我就会说到有点更高版本的详细信息中的这些函数的代码。

现在让我们看一下实际执行 XMLHTTP 请求的代码。
var szUrl;
	szUrl = "http://dadatop/wsXmlHttp/DynaProducts.asmx/" + methodName;
	
	if (wsParamValue != null)
	{
	
	      	szUrl += "?" + wsParamName + "=" + wsParamValue;
	}
	
// send the POST to the Web service
	objHttp.open("POST", szUrl, true);
	objHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	objHttp.send(strEnvelope);
变量szUrl包含用来调用 Web 服务,为清楚起见的 URL。如果再有采取对作为查询字符串值传递任何参数的语句。在您的环境中,可能要到 SOAP 信封中添加参数。两种方法都将正常工作。

接下来调用 open 方法的 XMLHTTP 对象。曾用过的前三个参数,open 方法 ;该方法、 URL 和一个布尔值,指定在调用是异步的。
重要提示如果您要做一个异步调用,因为我想在这里,您必须设置通过onreadystatechanged属性的回调函数。

设置请求标头的内容类型后,将作为 SOAP 信封使用我前面填充的字符串变量发送请求。

我们现在已通过的所有代码,使得 XMLHTTP 请求不都存在。现在让我们去看看,处理在浏览器的界面和处理来自 Web 服务调用的响应的代码。

首先,我们将看第一次加载页面时,将调用该函数。
function getCategories()
{

  var func = "getDataFromWS('GetCategories', 'CategoriesDS')";
  document.all.lblCategoryDropdown.innerText = 
"Please wait while data is retrieved...";
  window.setTimeout(func, 1);

  }
在该函数中我做的第一件事是创建一个变量来存储为getDataFromWS的函数签名。我这样做是因为我要调用此函数来调用getDataFromWS函数的结尾处的window.setTimeout 。这种方法的目的是请允许我在等待 Web 服务调用完成时向用户显示状态。请注意我正在更改 DIV 显示一条消息,指示要检索数据的 innerText。然后安排通过window.setTimeout调用getDataFromWS函数并设置其运行在一毫秒为单位)。

处理 Web 服务响应

请记住前面我用onreadystatechanged属性来配置一个回调函数。此外,请记住则对回调函数包含 switch 语句调用的特定函数基于该数据集名称。在这种情况下,我们的数据集名称是 CategoriesDS。因此,从回调函数将调用processCategory函数。让我们了解一下该函数以查看如何使用 XML DOM 中分析出来自 Web 服务的响应。
function processCategory()
{

  // get an XML data island with the category data
  objNodeList = objXmlDoc.getElementsByTagName("Categories");
 
  // add default value to the drop-down
  document.forms[0].drpCategory.options[0] = new Option("Select a Category", 0);

  // walk through the nodeList and populate the drop-down
  for (var i = 0; i < objNodeList.length; i++) 
  {
      var dataNodeList;
      var textNode;
      var valueNode;

      dataNodeList = objNodeList[i].childNodes;
      valueNode = dataNodeList.item(0);
      textNode = dataNodeList.item(1);

      document.forms[0].drpCategory.options[i + 1] = 
new Option(textNode.text, valueNode.text);
      document.all.lblCategoryDropdown.innerText = "Select a Category:";
      document.forms[0].drpCategory.style.visibility = "visible";
       
    }

  }
请记住getDataFromWS函数载入 XML 响应中的objXmlDoc对象。在processCategory函数中,我将采用该 XML,然后分析通过它来填充类别下拉列表。

我做的第一件事是创建一个IXMLDOMNodeList对象,该对象使用 XML 响应的一部分。我从 Web 服务调用中返回的数据集返回 diffgram,而我真正感兴趣,在该响应的只有部分是已插入到数据集中的数据表中的数据。我可以通过从包含数据表的 XML 块创建IXMLDOMNodeList对象获取的。

如果您看一下 Web 服务的代码,您将看到我将创建名为类别,并将其添加到数据集中的数据表。从 Web 服务返回的 XML 时,该数据集包含在<CategoriesDS>块,和数据表中的每一行包含在单独的<Categories>块,如在下面的 XML 文件中所示。

</Categories></CategoriesDS>下列文件是可从 Microsoft 下载下载以下文件:
收起这个图片展开这个图片
下载
立即下载 GetCategories.xml 软件包。
收起这个图片展开这个图片
下载
立即下载 WSXMLHTTP.exe 软件包。有关如何下载 Microsoft 支持文件的详细信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
119591 如何从联机服务获得 Microsoft 支持文件
Microsoft 扫描此文件中的病毒。Microsoft 使用发布该文件的日期时可用的最新病毒检测软件。该文件保存在安全性得到增强的服务器上,有助于防止对文件进行任何未经授权的更改。

若要获取包含该数据表中的 XML 块,请使用下面的代码:
objNodeList = objXmlDoc.getElementsByTagName("Categories");
这将返回一个包含<Categories>的每个节点的IXMLDOMNodeList对象。我然后循环访问该列表,使用 for 循环。</Categories>
// walk through the nodeList and populate the drop-down
  for (var i = 0; i < objNodeList.length; i++) 
  {
      var dataNodeList;
      var textNode;
      var valueNode;

      dataNodeList = objNodeList[i].childNodes;
      valueNode = dataNodeList.item(0);
      textNode = dataNodeList.item(1);

      document.forms[0].drpCategory.options[i + 1] = 
new Option(textNode.text, valueNode.text);
      document.all.lblCategoryDropdown.innerText = "Select a Category:";
      document.forms[0].drpCategory.style.visibility = "visible";
       
    }
我已经知道<Categories>的每个节点都需要的两个节点:<ID>节点和<CategoryName>节点。因此,我做的第一件事是创建新的IXMLDOMNodeList ,并向其中填充的子节点的当前<Categories>节点。</Categories> </CategoryName> </ID> </Categories>
dataNodeList = objNodeList[i].childNodes;
然后使用 item 方法来访问这两个节点,我需要填充我的下拉列表。在第一个节点包含来自数据库中,类别 id字段,第二个节点包含数据库中的类别名称字段。我创建新的选项对象、 将文字设置为类别名称、 将值设置为类别 id中,并将其添加到drpCategory下拉列表。在其余的函数中使用的代码使用相同的方法从 XML 响应所需的数据中拉出,并填充页面的某些部分。

注意我们正在处理少量的数据,因为使用 DOM 是拉出数据,我们需要一个好的办法。如果您正在处理大量的数据,您可以选择使用 XSLT 来代替。

如何使其所有工作

现在,我已经介绍了所有这些工作原理的切实可行的详细信息,就可以转到如何使用所包含的示例文件以查看其自己的工作了。

部署 Web 服务

若要部署 ASP.NET Web 服务,只需将解压缩所附的 Web 服务示例,向您的 Web 服务器的根目录。然后需要打开 DynaProducts.asmx 代码并更改连接字符串。至少,您需要输入 SA 密码。所做的更改后,请重新编译 Web 服务。

部署该 HTML 文件

HTML 文件包含名为szUrl ,其中包含指向 Web 服务的 URL 的变量。该函数的底部附近的getDataFromWS函数中,您将发现此变量。您将需要更改为您部署了上面的 Web 服务的 URL。

您已经部署了 Web 服务和 HTML 文件后,浏览到的 HTML 文件。加载后,类别下拉列表将使用第一个 XMLHTTP 请求对该 Web 服务填充。一旦已填充的选择某一类别可以甩掉填充产品下拉列表的下一步 XMLHTTP 请求。从产品下拉列表中选择一种产品,将会填充包含有关该产品的数据的表。

请注意,页上任何这些 XMLHTTP 请求在无法开机自检。这就是美的 XMLHTTP 请求。如果我有较大的网页上执行此操作,页上将还保持滚动位置而不是"闪烁"在用户。如果您问我,这是一些非常强大的东西 !

一件事: 在本文中,我使用 XMLHTTP 查询 Web 服务。我可以轻松使用它做的 ASPX 页或 ASP 页的请求。如何让这种技术使用的可能性是无穷尽的。我希望您发现 XMLHTTP 您未来的 Web 应用程序开发中很有用。
一直以来,尽情地提交所需的主题的意见在将来解决列或在使用 Microsoft 知识库文章 诚征意见 表单。

属性

文章编号: 893659 - 最后修改: 2013年6月28日 - 修订: 6.0
这篇文章中的信息适用于:
  • Microsoft ASP.NET 1.0
  • Microsoft ASP.NET 1.1
关键字:?
kbgraphic kbscript kbxml kbhowto kbmt KB893659 KbMtzh
机器翻译
重要说明:本文是由 Microsoft 机器翻译软件进行的翻译并可能由 Microsoft 社区通过社区翻译机构(CTF)技术进行后期编辑,或可能是由人工进行的翻译。Microsoft 同时向您提供机器翻译、人工翻译及社区后期编辑的文章,以便对我们知识库中的所有文章以多种语言提供访问。翻译的文章可能存在词汇、句法和/或语法方面的错误。Microsoft 对由于内容的误译或客户对内容的使用所导致的任何不准确、错误或损失不承担责任。
点击这里察看该文章的英文版: 893659
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失所导致的之损害、数据或利润不负任何责任。

提供反馈

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com