决战.NET
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.3 XMLHttpRequest的诞生

阻止页面刷新的方法其实很简单,页面刷新是为了要将数据送回服务器端,然后由服务器端取得更新后的页面来显示,那么如果能在不刷新页面的情况下,将数据送往服务器端,不就能解决页面刷新的问题了吗?只是在浏览器的原始设计概念中,要将数据送到服务器端就得背负刷新页面的原罪,除非改变原始设计概念,否则问题就是无解!很幸运地,由微软推出的Internet Explorer,简称IE的浏览器打破了这个僵局,在XML盛行初期,修改了一部分浏览器的设计概念,允许设计师在JavaScript中创建一个ActiveX对象:XMLHttpRequest,利用这个对象,设计师可以用JavaScript将数据直接送到服务器端而不引发页面刷新的操作,只是在当时这个功能并不算公认的浏览器标准,在众多浏览器不支持的情况下,XMLHttpRequest 也只能静静躺在实验室中。直到今日,除IE外的其他主流浏览器如Netscapce、Mozilla都已支持同样的功能,让 XMLHttpRequest 在一瞬间成了标准之外的热门技术,以此对象为核心的新名词AJAX“全名是Asynchronous JavaScript And XML”也就诞生了,Asynchronous 的语义来源于 XMLHttpRequest 所采取的异步行为模式,使用XMLHttpRequest 发送数据时,必须指定一个接收返回数据的函数,送出数据后,客户端不必停下来等候数据的返回,XMLHttpRequest 取得返回数据后会调用指定的函数将数据传过去,图1-2是其流程图。

图1-2 在创建 XMLHttpRequest 对象时,指定processRequest函数为收取返回数据的函数,在XMLHttpRequest的send函数被调用后,XMLHttpRequest即发送要求,需特别注意的一点是,send函数不会像传统函数调用般等待要求被处理后而收取返回值,而是直接返回,继续运行下面的JavaScript程序,或将主导权还给浏览器,此行为模式正是AJAX中的Asynchronous 语义来源。AJAX中的J代表的是JavaScript,虽然IE可以用VBScript来使用XMLHttpRequest对象,但是JavaScript才是诸多浏览器所支持的标准语言,因此AJAX中的J代表的是启动XMLHttpRequest对象时所使用的语言。AJAX中的第二个A代表的是“And”,

true

图1-2

最后的“X”代表的是使用 XMLHttpRequest 对象时所使用的数据协议,也就是XML文件格式。好了,了解 XMLHttpRequest 的历史后,现在就以一个实例(如程序1-1)来看看 XMLHttp-Request究竟有何神妙之处,为什么可以引发第二次的网页革命。

程序1-1

    Samples\1\XMLHttpRequestDemo\Default.aspx
    <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs"
    Inherits="_Default" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>Untitled Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
        <script language=javascript>
          var req;
          function loadXMLDoc(url)
          {
            req = false;
            //视不同浏览器,使用不同的方式创建XMLHttpRequest对象
            if(window.XMLHttpRequest && !(window.ActiveXObject)) //FireFox
            {
              try
              {
                req = new XMLHttpRequest();
              }
              catch(e)
              {
                req = false;
              }
            }
            else if(window.ActiveXObject)  //IE
            {
              try
              {
                req = new ActiveXObject("Msxml2.XMLHTTP");
              }
              catch(e)
              {
                try
                {
                  req = new ActiveXObject("Microsoft.XMLHTTP");
                }
                catch(e)
                {
                  req = false;
                }
              }
            }
            if(req)
            {
                //指定要求处理后,收取返回值的函数
                req.onreadystatechange = processReqChange;
                //开启通信管道
                req.open("GET", url, true); //use get method
                //发送要求,请注意,send函数不会等待返回值,而是直接返回。
                req.send("");
            }
          }
          function processReqChange()
          {
          if (req.readyState == 4)  //readyState = 4 代表要求已被处理
          {
          if (req.status == 200) //200代表服务器端正常的处理要求
            //responseXML中包含服务器返回的XML数据。
            document.getElementById("Button1").value =
            req.responseXML.getElementsByTagName('Result')[0].getAttribute('Val');
            else
            alert("There was a problem retrieving the XML data:\n"+req.statusText);
          }
      }
      function callBack()
      {
          loadXMLDoc('<%=Request.Url%>?CallBack=true');
      }
    </script>
      <asp:Button ID="Button1" UseSubmitBehavior=false runat="server"
                    Text="Button" OnClientClick="callBack(); return false;"/>
      <br />
      <asp:Label ID="Label1" runat="server"></asp:Label>
      </div>
      </form>
    </body>
    </html>
    Samples\1\XMLHttpRequestDemo\Default.aspx.cs
    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.QueryString["CallBack"] != null)
            {
                Response.ContentType = "text/xml";
                Response.Write(
                  "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Result Val='TEST'/>");
                Response.End();
            }
        }
    }
      图1-3为此程序运行后,点击按钮后的结果。
true

图1-3

请注意,在运行 XMLHttpRequest 期间不会引发任何的页面刷新操作,就是这个设计使得XMLHttpRequest在诞生多年后,一跃成为引发第二波网页革命的关键。