zoukankan      html  css  js  c++  java
  • Ajax底层代码简析(可直接用的框架)

            近来忙毕业设计,又很长时间没写blog了。
            学ajax也有段时间了,理论是看了不少,也对MagicAjax框架做了下了解,当然要吃透它还是有很长的路要走。
            一直觉得对Ajax底层的代码应该总结一下。其实很底层的代码是比较简洁明了的,但功能却比较简单。一般我们都用Send(null).以前我一直在想我怎么来控制当异步传送Http请求时要调用的后台的指定的(我想用的)代码,现在终于明白了(唉,对自己的智商表示怀疑),那就要在Send方法中传送参数。参数中应该包括事件的触发者和它的参数,还有就是ViewState的值。
            具体代码如下(里面我加了些注释,后面不再解释):

      1__PageForm = null;
      2
      3function AjaxCallObject()
      4{
      5    this.Init();
      6}

      7
      8AjaxCallObject.prototype.Init = function()
      9{
     10    this.XmlHttp = this.GetHttpObject();
     11}

     12 
     13AjaxCallObject.prototype.GetHttpObject = function()
     14
     15    var xmlhttp;
     16    if (!xmlhttp) 
     17    {
     18        try 
     19        {
     20            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
     21        }
     
     22        catch (e) 
     23        {
     24            xmlhttp = false;
     25        }

     26    }

     27    return xmlhttp;
     28}

     29
     30AjaxCallObject.prototype.HookAjaxCall = function()
     31{
     32    __PageForm = document.getElementById('Form1');
     33    if (typeof __doPostBack != 'undefined')
     34        __doPostBack = this.DoPostBack;
     35}

     36
     37// Replaces normal __doPostBack
     38AjaxCallObject.prototype.DoPostBack = function(eventTarget, eventArgument)
     39{    
     40    AJAXCbo.DoAjaxCall(eventTarget, eventArgument);
     41}

     42 
     43AjaxCallObject.prototype.DoAjaxCall = function(eventTarget, eventArgument)
     44{
     45    var theData = '';
     46    var theform = __PageForm;
     47    
     48    if(theform == null)
     49    {
     50        return;
     51    }

     52    
     53    var thePage = theform.action;//得到页面地址
     54    var eName = '';
     55
     56    theData  = '__EVENTTARGET='  + this.EncodePostData(eventTarget.split("$").join(":")) + '&';//得到事件的发起者,也就是object Sender
     57    theData += '__EVENTARGUMENT=+ this.EncodePostData(eventArgument) + '&';//得到参数,就是EventArgs e
     58
     59    var elemCount = theform.elements.length;
     60    forvar i=0; i<elemCount; i++ )
     61    {
     62        curElem = theform.elements[i];
     63        eName = curElem.name;
     64        if( eName && eName != '' && curElem.tagName != "EMBED")
     65        {
     66            if( eName == '__EVENTTARGET' || eName == '__EVENTARGUMENT' )
     67            {}
     68            else
     69            {
     70                var type = curElem.type;
     71                var val = curElem.value;
     72
     73                if ( type == "submit" || type == "button" )
     74                    continue;
     75
     76                val = this.EncodePostData(val);
     77
     78                if ( type == "select-multiple" || type == "select-one" )
     79                {
     80                    var selectLength = curElem.options.length;
     81                    var optNameStr = this.EncodePostData(eName);
     82                    for (var j=0; j < selectLength; j++)
     83                        if (curElem.options[j].selected)
     84                            theData = theData + optNameStr + '=+ this.EncodePostData(curElem.options[j].value) + '&';
     85                }

     86                else if ( (type != "checkbox" && type != "radio"|| curElem.checked )
     87                {
     88                    theData = theData + this.EncodePostData(eName) + '=+ val + '&';
     89                }

     90            }

     91        }

     92    }

     93  
     94    if (theData.substr(theData.length-1== "&")
     95        theData = theData.substr(0, theData.length-1);
     96        //alert(theData);
     97        
     98    ifthis.XmlHttp )
     99    {        
    100         //注释的是旧的代码,有问题,回送回来的状态都是0,原因还不明
    101        /*AJAXCbo = new AjaxCallObject();
    102
    103        if( this.XmlHttp.readyState == 4 || this.XmlHttp.readyState == 0 )
    104        {
    105            // Asynchronous
    106            this.XmlHttp.open("POST", thePage, true);
    107            this.XmlHttp.onreadystatechange = function(){ AJAXCbo.ReadyStateChange(); };
    108            this.XmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    109            this.XmlHttp.send(theData);
    110        }*/

    111        var oThis = this;
    112        AJAXCbo = new AjaxCallObject();
    113
    114        ifthis.XmlHttp.readyState == 4 || this.XmlHttp.readyState == 0 )
    115        {
    116            ajaxCallType = "async";
    117        
    118            if ( ! ajaxCallType || ajaxCallType.toLowerCase() != "sync")
    119            {
    120                // 异步传输
    121                this.XmlHttp.open("POST", thePage, true);
    122                this.XmlHttp.onreadystatechange = function(){ oThis.ReadyStateChange(); };
    123                this.XmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    124                this.XmlHttp.send(theData);
    125            }

    126            else
    127            {
    128                // 同步传输,页面会刷新
    129                window.setTimeout(
    130                    function()
    131                    {
    132                        oThis.XmlHttp.open("POST", thePage, false);
    133                        oThis.XmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    134                        oThis.XmlHttp.send(theData);
    135
    136                        if( oThis.XmlHttp.status == 200 && oThis.XmlHttp.statusText == "OK" )
    137                            oThis.OnComplete(oThis.XmlHttp.responseText, oThis.XmlHttp.responseXML);
    138                        else
    139                            oThis.OnError(oThis.XmlHttp.status, oThis.XmlHttp.statusText, oThis.XmlHttp.responseText);
    140                    }
    1);
    141            }
                
    142        }

    143    }

    144    return true;
    145}

    146
    147/*AjaxCallObject.prototype.OnLoading = function()
    148{
    149  // Loading
    150}
    151
    152AjaxCallObject.prototype.OnLoaded = function()
    153{
    154  // Loaded
    155}
    156
    157AjaxCallObject.prototype.OnInteractive = function()
    158{
    159  // Interactive
    160}
    161*/

    162AjaxCallObject.prototype.OnComplete = function(responseText, responseXml)
    163{
    164    this.SetHtmlOfPage(responseText);
    165    return true;
    166}

    167
    168/*AjaxCallObject.prototype.OnAbort = function()
    169{}*/

    170
    171AjaxCallObject.prototype.OnError = function(status, statusText, responseText)
    172{
    173    if (status==200)
    174    {
    175        // a weird bug of Opera sometimes invokes OnError when there's no error
    176        this.OnComplete(responseText);
    177        return;
    178    }

    179
    180    document.close();    // for IE
    181    document.write(responseText);
    182    document.close();    // for Firefox
    183}

    184
    185AjaxCallObject.prototype.ReadyStateChange = function()
    186{
    187    /*if( this.XmlHttp.readyState == 1 )
    188    {
    189        this.OnLoading();
    190    }
    191    else if( this.XmlHttp.readyState == 2 )
    192    {
    193        this.OnLoaded();
    194    }
    195    else if( this.XmlHttp.readyState == 3 )
    196    {
    197        this.OnInteractive();
    198    }
    199    else */

    200    //alert("ly");
    201    //alert(this.XmlHttp.readyState);
    202    ifthis.XmlHttp.readyState == 4)
    203    {
    204        /*if( this.XmlHttp.status == 0 )
    205            this.OnAbort();
    206        else*/

    207        ifthis.XmlHttp.status == 200 )
    208        {
    209            this.OnComplete(this.XmlHttp.responseText, this.XmlHttp.responseXML);
    210        }

    211        else
    212        {
    213            this.OnError(this.XmlHttp.status, this.XmlHttp.statusText, this.XmlHttp.responseText);   
    214        }

    215    }

    216}

    217
    218AjaxCallObject.prototype.EncodePostData = function(data)
    219{
    220    return data.split("%").join("%25").split("=").join("%3d").split("&").join("%26").split("+").join("%2b");
    221}

    222
    223AjaxCallObject.prototype.SetHtmlOfPage = function(html)
    224{
    225    document.close();    // for IE
    226    document.write(html);//用新的html代码替代页面上的html代码
    227    document.close();    // for Firefox
    228}

    229
    230var AJAXCbo = new AjaxCallObject();
            代码长了点,不过可以直接用了,只要在相应的后台代码中给服务器控件加段代码就成了。比如说,Web页面上放了个按钮控件,ID为Button1,那么在后台代码的Page_Load中加上下面一段代码:
    Button1.Attributes.Add("onclick","modify();");
    这里的modify是我在页面的html里定义的一个方法,其内容是:
    <script>
                
    function modify()
                
    {
                    
    if(typeof(AJAXCbo) == 'undefined')
                    
    {
                        
    var AJAXCbo = new AjaxCallObject();
                    }

                    AJAXCbo.HookAjaxCall();
                }

            
    </script>
             到这就结束了,你可以看到无刷新更新的效果了。接下来的工作就是想办法更进一步,只把更新过的值传到相应的控件,该怎么做还需要继续努力了,呵呵。
            水平有限,难免有错误,望能和大家多多交流!
     例子代码下载:/Files/fxb248/ajaxtestaaa.rar
  • 相关阅读:
    Multiple markers at this line
    用递归和位移进行枚举子集合
    Android开发如何双击返回键退出程序
    Android ImageView设置图片原理(下)
    北大OJ百练——2721:忽略大小写比较字符串大小
    场景示例 Nginx 访问日志
    2 插件管理
    第一章 入门示例
    zabbix 通过gateway 获取远程主机的JMX信息
    zabbix 通过gateway 获取远程主机的JMX信息
  • 原文地址:https://www.cnblogs.com/fxb248/p/408780.html
Copyright © 2011-2022 走看看