zoukankan      html  css  js  c++  java
  • 关于Ajax的一揽子工程(1)

    关于Ajax的一揽子工程

    --异步数据交互

    /*内部培训用的,写得非常基础*/
      
            Ajax不仅仅就是XMLHttpRequest这么简单。

      在以前,我们写客户端的代码一般是实现几个效果,做一下数据校验这些简单的事情。那时,客户端的代码一般不会太多,也不会很复杂,而且大部分情况下这些代码并不是业务过程的核心代码,一定程序上,这些代码是可有可无的,如果它们不能很好的工作,也并不会影响大局。

      但现在情况不同了,我们用Ajax做的工程,一方面客户端代码量急骤增加。代码量急聚增中后,代码的管理难度急骤增加,这时我们就需要用到一些工程化管理方法来组织我们的代码,所以我们可以看到很多成熟的Ajax客户端框架都采用了模拟面向对象的方式来实现。另一方面,客户端的不少代码直接和我们的业务逻辑相关,可以说客户端的脚本直接决定我们的程序能不能完成任务,这样的话,我们在写客户端脚本时,不能不更加小心,由此,我们可以看到,Ajax已经涌现出了不少的设计模式,人们也更加重视对Web standard的遵守,也更加重视的cross-browser(跨浏览器)能力。

      因此,可以说关于Ajax,有一揽子注意事项,有一揽子工程。

           今天我们先来解决最基础的问题:异步数据交互方式。

           总的来说,常用的异步数据交互方式有二种:frameset/iframe和XMLHttpRequest。

           frameset的一般做法是在框架中做一个高度或宽度为0的隐藏帧。代码如下:

     <frameset rows="100%,0" frameborder="0">
        
    <frame name="displayFrame" src="display.htm" noresize="noresize" />
        
    <frame name="hiddenFrame" src="about:blank" noresize="noresize" />
    </frameset>

            然后再用脚本操作hiddenFrame负责刷数数据,并把返回给自己的内容更新到显示帧。比如在显示页面的一个按钮注册如下click事件处理程序:

            function requestCustomerInfo() {
                
    var sId = document.getElementById("txtFormFiled").value;
                top.frames[
    "hiddenFrame"].location = "GetNewData.aspx?id=" + sId;
            }
             然后,隐藏的帧去获取数据,获取数据之后,同样通过脚本来更新显示帧中的内容:
        <script type="text/javascript">
            window.onload 
    = function () {
                
    var divInfoToReturn = document.getElementById("divInfoToReturn");
                top.frames[
    "displayFrame"].document.getElementById("divInfo").innerHTML = divInfoToReturn.innerHTML;        
            };
        
        
    </script>

    </head>
    <body>
        
    <div id="divInfoToReturn"><%=Your return content%><div>
    </body>
           采用这种方式实现post比较的麻烦,需要用DOM操作把显示帧中的form以及form中的值都复制一份到隐藏帧,再通过隐藏帧来代替显示帧提交表单,一般是通过显示帧中的表单提交按钮的onclick事件截获表单提交事件来实现。

           HTML4.0以后我们可以采用iframe,iframe不需要帧集,可以放在文档的任何地方,可以通过脚本创建,所以它更灵活。
            function createIFrame() {
                
    var oIFrameElement = document.createElement("iframe");
                oIFrameElement.width
    =0;
                oIFrameElement.height
    =0;
                oIFrameElement.frameBorder
    =0;
                oIFrameElement.name 
    = "hiddenFrame";
                oIFrameElement.id 
    = "hiddenFrame";
                document.body.appendChild(oIFrameElement);
                
                oIFrame 
    = frames["hiddenFrame"];

            }


            其它方面来讲,使用iframe和使用帧差别不大。
            虽然Ajax流行之后,人们已经更倾向于使用XMLHttpReqeust,但隐藏帧和iframe技术仍然是一项可用的技术(我就曾采用这种技术实现过不刷新的聊天室),而且由于帧能维护浏览器的历史记录,所以现在大型的Ajax应用都综合采用XMLHttp和帧,才尊重人们的“前进”、“后退”按钮习惯。
            从IE5.0开始,主流的浏览器现在基本都能很好的支持XMLHttp对象。因为XMLHttp对象是一个Javascript的对象,它更易于创建和管理(特别是在一个JS类库中),也更符合程序员编辑习惯(和帧方式相比,必竟帧是界面的东西)。
            不幸的是不同的浏览器实现XMLHttp的方式并不一样(IE用ActiveX方式,而FireFox/Safari/Opera则是XMLHttpRequest),所以,为了cross-browser,我们创建XMLHttp对象的代码可能要写得复杂一点。
    //众多的ActiveX的XMLHttp版本
    var XML_VERS = ["MSXML2.XmlHttp.5.0""MSXML2.XmlHttp.4.0"
                    
    "MSXML2.XmlHttp.3.0""MSXML2.XmlHttp",
                    
    "Microsoft.XmlHttp"];

    function XmlHttp(){}

    //创建Requestor
    XmlHttp.createRequest = function () {

        
    if (XMLHttpRequest) {//Non-IE
            return new XMLHttpRequest();
        }
        
    else if (ActiveXObject) {//IE
            forvar i = 0 ; i < XML_VERS.length ; i ++){
                
    try{
                    
    var oXmlHttp = new ActiveXObject(XML_VERS[i]);
                    
    return oXmlHttp;
                } 
    catch (e){}
                    
            }
        }
    };

    之后,我们就可以通过 var oXmlHttp = XmlHttp.createRequest();这样的语句来创建cross-browser的XmlHttp请求对象了。
           之后,我们就可以通过 var oXmlHttp = XmlHttp.createRequest();这样的语句来创建cross-browser的XmlHttp请求对象了。
           下面我们以一个Get请求为例说明使用XmlHttp的步骤:
    //发送一个get请求
    function getRequest(){
        
    var oXmlHttp = XMLHttp.createRequest();//创建XmlHttp对象

        oXmlHttp.open(
    "get","server_url.aspx?p=params",true);
    //open(方式,路径,是否异步请求)
        oXmlHttp.onreadystatechange = function(){
    //注册状态变化时的处理函数
            if(oXmlHttp.readyState == 4){
    //readyState有5种:
    //
    0-未初始化,1-载入中,2-已载入,3-交互中,4-完成
                if(oXmlHttp.status == 200){
    //status是http状态码,404为资源未找到,203为重定向,401请求验证等等,
    //
    如果没有通过IIS等Web服务宿主,这个状态码可能没有
    //
    200表示一切正常,可以正常处理结果
                    handleResult(oXmlHttp.responseText);//responseText返回响应文本,
    //
    也可用responseXML返回响应的XML,结果为XMLDOM对象
                }
                
    else{
                    handleError(oXmlHttp.statusText);
    //statusText为状态结果,非IE可能没有这个属性
                }
            }
        }

        oXmlHttp.send(sBody);
    //一切准备工作做好后,发送请求
    }

           XMLHttp对象发送post请求相对来说,要简单一些:

    //把表单的所有域组织成key1=value1&key2=value2...的方式
    function getRequestBody(oForm){
        
    var aParams = new Array();    
        
    forvar i = 0 ;i < oForm.elements.length ; i ++){
            
    var sParam = encodeURIComponent( oForm.element[i].name);//用encodeURIComponent过滤URL字符
            sParam += “=”;
            sParam 
    += encodeURIComponent( oForm.elements[i].value);
            aParams.push(sParam);
        }

        
    return aParams.join(“&”);
    }


    //send a post request
    function sendRequest(){
        
    var oForm = document.forms[0];
        
    var sBody = getRequestBody(oForm);//获得请求体
        var oXmlHttp = XMLHttp.createRequest();
        oXmlHttp.open(
    "post",oForm.action,true);//方式设成post
        oXmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");//设置正确的post的Content-Type
        oXmlHttp.onreadystatechange = function(){
            
    if(oXmlHttp.readyState == 4){
                
    if(oXmlHttp.status == 200){
                    handleResult(oXmlHttp.responseText);
                }

                
    else{
                    handleError(oXmlHttp.statusText);
                }

            }

        }


        oXmlHttp.send(sBody);
    //发送请求时带上请求体
    }

            使用XMLHttp就这么简单,但是要注意的是Javascript中的same origin policy,就是不同域名的对象之间不能互访(包括二级域名),所以不要在www.site1.com的页面中用XmlHttp请求www.site2.com中的地址。虽然用帧可以在浏览器中同时请求多个域的页面,但它们之间并不能互访,解决方法后面内容再进行探讨。
            再一个就是服务器向客户端响应内容时,最好在响应头中加上Cache-Control : no-cache设置,以解决缓存机制带来的不更新数据问题。
    //C#代码
    Response.Cache.SetCacheability(HttpCacheability.NoCache);

            异步交互的方法除了以上两种,还可以使用XMLDOM对象来进行,不过XMLDOM只支持获取XML数据,下篇我们再介绍XMLDOM对象,以及脚本中的XML/XPath/XSLT技术。

    (未完待续......)
  • 相关阅读:
    [论文收集] ICWS 2008论文
    [论文笔记] The Impact of Service Pricing Models on Service Selection (ICIW, 2009)
    [论文摘录] Web Service QoS的几个研究方向
    [论文笔记] SOA Middleware Support for Service Process Reconfiguration with EndtoEnd QoS Constraints (ICWS 2009)
    回顾与打算
    [论文笔记] Fast Quality Driven Selection of Composite Web Services (ECOWS, 2006)
    [论文调查] (Mixed) Integer Programming方法在Web Service领域应用概况
    [论文笔记] Gradual Removal of QoS Constraint Violations by Employing Recursive Bargaining Strategy for Optimizing Service Composition Execution Path (ICWS, 2009)
    [论文收集] ICSOC 2008 论文
    [论文泛读] 论文泛读2篇
  • 原文地址:https://www.cnblogs.com/think/p/AjaxSolution_1.html
Copyright © 2011-2022 走看看