AjaxPro 内部机制探讨-asp.net的结合,Ajax技术(2)

ajax|asp.net

五、Invoke 函数

  Invoke 函数是核心所在,前面我画的流程图中已经简单地描述了它的主要流程。不过这个函数太重要了,这里还是列出它的全部源码:

 

 1AjaxPro.Request = Class.create();
 2AjaxPro.Request.prototype = (new AjaxPro.Base()).extend({
 3    invoke: function(method, data, callback) {
 4        var async = typeof callback == "function" && callback != AjaxPro.noOperation;
 5        var json = AjaxPro.toJSON(data) + "\r\n";
 6
 7        if(AjaxPro.cryptProvider != null)
 8            json = AjaxPro.cryptProvider.encrypt(json);
 9
10        this.callback = callback;
11
12        if(async) {
13            this.XMLHttp.onreadystatechange = this.doStateChange.bind(this);
14            if(typeof this.onLoading == "function") this.onLoading(true);
15        }
16           
17        this.XMLHttp.open("POST", this.url, async);
18        this.XMLHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
19        this.XMLHttp.setRequestHeader("Content-Length", json.length);
20        this.XMLHttp.setRequestHeader("Ajax-method", method);
21       
22        if(AjaxPro.token != null && AjaxPro.token.length > 0)
23            this.XMLHttp.setRequestHeader("Ajax-token", AjaxPro.token);
24
25        if(MS.Browser.isIE)
26            this.XMLHttp.setRequestHeader("Accept-Encoding", "gzip, deflate");
27        else
28            this.XMLHttp.setRequestHeader("Connection", "close");    // Mozilla Bug #246651
29
30        if(this.onTimeout != null && typeof this.onTimeout == "function")
31            this.timeoutTimer = setTimeout(this.timeout.bind(this), this.timeoutPeriod);
32
33        this.XMLHttp.send(json);
34       
35        json = null;
36        data = null;
37        delete json;
38        delete data;
39       
40        if(!async) {
41            return this.createResponse();
42        }
43       
44        return true;   
45    }
46});
47

  嗯,相当复杂啊。我们慢慢地看。

  AjaxPro.Request 类当然不是只有 Invoke 一个函数,这里省去了其它函数。嗯,我们看到,AjaxPro.Request 也是从 AjaxPro.Base “继承”下来的。

  第4行的 async,字面上理解就是指异步,这一行什么意思?嗯,如果传进来的 callback 类型是函数,并且不是无操作,那就认为是异步的。

  第5行的 json,它可是相当重要啊。这里调用了 AjaxPro.toJSON 方法把传进来的数据进行了某种编码,本例中这个数据当然就是从 doTest1_next 一路传进来的 TextBox 里我们输入的字符串值了,这个函数的实现,本文也不再列出,可以参见 core.ashx 文件。

  接下来第7到8行,如果提供了加密,那么就对 json 进行加密。这个好理解。

  第12到15行,如果是异步的,那么这里将 doStateChange 函数绑定到 onreadystatechange 事件上去。嗯,这里的绑定其实也是在 core.ashx 文件里声明的一个方法,本文不再阐述它的实现了,大家有兴趣,可以自己去看。绑定完成后,当服务端完成操作后,doStateChange 函数会被调用,这时可以进行更改页面的工作。此外,这里还检测了一下 onLoading 事件。

  第17行到第33行可谓核心代码,我们知道 Ajax 就是使用的 XMLHttpRequest 来完成无刷新页面的。这里我们可看到 this.XMLHttp 被用来进行了请求封装。其中值得我们注意的,Content-Length 使用的 json.length,Ajax-method 则使用的就是传进来的 AjaxMethod 方法名称,本例中为 EchoInput。第30、31行设置了超时处理,当然了,页面不能死等嘛。第33行则将 json 发送到服务端。

  接下来的第41行,我们看到如果不是异步操作的话,此处将直接调用 createResponse 函数获得响应。那如果是异步操作呢?记得我们设置了 doStateChange 吧?异步的返回处理就是它的事了。createResponse 函数后面再介绍。

  六、解释“继承”

  前面我们好几次看到貌似继承。当然它们都仅仅是貌似而已。看看以下 core.ashx 中的代码就明白了:

1Object.extend = function(destination, source) {
2    for(property in source) {
3        destination[property] = source[property];
4    }
5    return destination;
6}
7
  哈哈,所谓的“继承”,其实只是个属性拷贝而已。

  七、this.XMLHttp 从何而来?

  前面我们看到了 this.XMLHttp 大显神威。那么它是哪儿来的?看看 AjaxPro.Request 类的 initialize 函数吧(有删节):

1initialize: function(url) {
2    this.XMLHttp = new XMLHttpRequest();
3}
4
  是了,XMLHttp 只是 XMLHttpRequest 的一个实例。那么 XMLHttpRequest 的定义呢?

 1var lastclsid = null;
 2if(!window.XMLHttpRequest) {
 3
 4    function getXMLHttp(clsid) {
 5        var XMLHttp = null;
 6        try {
 7            XMLHttp = new ActiveXObject(clsid);
 8            lastclsid = clsid;
 9            return XMLHttp;
10        } catch(ex) {}
11    }
12   
13    window.XMLHttpRequest = function() {
14        if(lastclsid != null) {
15            return getXMLHttp(lastclsid);
16        }
17   
18        var XMLHttp = null;
19        var clsids = ["MsXML2.XMLHTTP.6.0","MsXML2.XMLHTTP.5.0","MsXML2.XMLHTTP.4.0","MsXML2.XMLHTTP.3.0","MsXML2.XMLHTTP.2.6","Microsoft.XMLHTTP.1.0","Microsoft.XMLHTTP.1","Microsoft.XMLHTTP"];
20
21        for(var i=0; i<clsids.length && XMLHttp == null; i++) {
22            XMLHttp = getXMLHttp(clsids[i]);
23        }
24       
25        if(XMLHttp == null) {
26            return new IFrameXMLHttp();
27        }
28
29        return XMLHttp;
30    }
31}
32
  哦,原来是在这里真正创建的。说到底还是一个 ActiveXObject 啊。关于这个本文也不再多提。不过代码中还需要注意的一点是,
如果把第19行列出的一大堆clsids 都处理过了还没有得到对象怎么办?注意到第26行 new 了一个 IFrameXMLHttp。

  IFrameHttp 是在 core.ashx 中定义的,它基本上完全模拟了 ActiveXObject 对象的功能。想研究研究的,自己看源码吧。篇幅所限,这里不多讲啦。

  八、doStateChange 函数

  嗯,前面已经提过,异步的话 doStateChange 函数将会在服务端返回后执行,看看它的源码呢:

 1doStateChange: function() {
 2    if(this.onStateChanged != null && typeof this.onStateChanged == "function")
 3        try{ this.onStateChanged(this.XMLHttp.readyState); }catch(e){}
 4
 5    if(this.XMLHttp.readyState != 4)
 6        return;
 7
 8    if(this.XMLHttp.status == 200) {
 9        if(this.timeoutTimer != null) clearTimeout(this.timeoutTimer);
10        if(typeof this.onLoading == "function") this.onLoading(false);
11
12        this.XMLHttp.onreadystatechange = AjaxPro.noOperation;
13
14        this.callback(this.createResponse());
15        this.callback = null;
16
17        this.XMLHttp.abort();
18    }
19},
20
  如果 status 是 200,也就是 OK,那么清除掉超时处理函数,处理 onLoading 事件,最后使用 callback 调用 createResponse 函数。还记得如果不是异步的话,createResponse 将会直接调用而不是通过 doStateChange 吧。

  九、createResponse 函数

 1createResponse: function() {
 2    var r = new Object();
 3    r.error = null;
 4    r.value = null;
 5
 6    var responseText = new String(this.XMLHttp.responseText);
 7
 8    if(AjaxPro.cryptProvider != null && typeof AjaxPro.cryptProvider == "function")
 9        responseText = AjaxPro.cryptProvider.decrypt(responseText);
10
11    eval("r.value = " + responseText + ";");
12
13    if(r.error != null && this.onError != null && typeof this.onError == "function")
14        try{ this.onError(r.error); }catch(e){}
15
16    responseText = null;
17
18    return r;
19}
  如果前面的 json 也就是 Request 是加过密的,这里就需要对 responseText 进行解密。完了之后得到 r.value,r 将会被返回并提供给 callback 函数。本例中将最终传回 doTest1_callback,r 被传入它的 res 参数。最后更新文本框下的字符串,整个 Ajax ClientScript 的流程就差不多是完成了。

  十、简单总结一下

  呼,长出一口气。总算可以告一段落了,AjaxPro 服务端的拆解过段时间再说吧。

  在分析 ClientScript 端的时候真是大有感触,JavaScript 其实远比人们想象的强大和管用。其实我同大多数人一样,起初也对它很不感冒,但是之前曾有两件事让我改变了观念。其一是阅读了黄忠成的《深入剖析 ASP.NET 组件设计》,才发现原来许多强大炫目的 ASP.NET 的控件,其实都是用的 JavaScript 实现。其二是在研究国外某文档浏览器实现的时候,发现人家使用 JavaScript 在 IE 下相当完美地实现了强大灵活有如桌面程序的界面和功能,真是吃惊不小。当时就发现了自己对 JavaScript 的了解实在是严重汗颜,惭愧无地。无奈平时没有多少时间去学习提高自己,只能偶尔抽抽空余时间了解了解,充充电吧。

  相信 JavaScript 之类的脚本必将在未来的 Web 应用中大展身手。

 

时间: 2024-11-08 21:17:10

AjaxPro 内部机制探讨-asp.net的结合,Ajax技术(2)的相关文章

AjaxPro 内部机制探讨

应当承认我这人实在算不上弄潮儿,Ajax 早已流行得一塌糊涂,我却始终没有来研究一下这个东东.上次做网站的时候,BOSS 就跟我讲过,可以参考一下 Ajax 的技术,我嘴上答应,心里却不是十分的在乎.究其原因,一来是我这人比较固步自封,二来起初确实也没太相信 Ajax 真有 BOSS 说的那么神奇. 转变是从昨天天始的,这一周在公司主要精力都是在用 C++ 写 framework,不得不承认它比较辛苦,细枝末节之处非常之烦,昨天下午呆着呆着就不想干活了,就开始四处游荡,正好看到我们自己也有项目已

传统的ASP.NET网页与AJAX技术

ASP.NET AJAX本身被设计用来延伸既有的ASP.NET网页功能,开发人员透过这些延伸工具,不需要修改现有的程式码,就可以为网页加入AJAX的功能,对于ASP.NT网页的开发人员来说,ASP.NET AJAX代表的是一种进化而非革命. AJAX技术并不会推翻现有的ASP.NET,就如同它的名称,ASP.NET AJAX与ASP.NET是并存的,我们来看看传统的ASP.NET网页与运用了AJAX技术的网页它们之间的差异,底下是传统的ASP.NET网页: ASP.NET网页的每一个要求,会伴随

利用.net的内部机制在asp.net中实现身份验证

在.net内部存在一些默认机制,具体说来有如下: (1)如果类的实例字段没有赋初始值,那么它们就会被赋默认值,对于引用类 型字段的默认值为null,对于简单值类型字段(即数值类型)默认值为对应形式 的0(如sbyte.byte.short.ushort.int.uint.long 和 ulong都是0,而char 类型字段的默认值值是'\0x0000',float类型字段是0.0f,double类型字段是 0.0d等等). (2)如果类中赋初值的静态字段,那么自动生成一个静态构造函数,在静态函

ASP.NET中有哪些AJAX技术,相互是什么关系?

问题描述 以前VS2005中接触过一下AJAX Extensions,现在在VS2010中新建项目怎么找不到新建AJAX Enabled Webiste这个选项了?据说是集成在.net Framework3以上版本中了.在VS2010新建项目中有两个选项:asp.net ajax 服务器控件asp.net ajax 服务器控件扩展此外还有一个AjaxPro.net框架,再有VS2010中新建的项目中好象已经集成了JQuery框架,这个也是AJAX的吧,感觉很混乱,搞不清这些东西之间是个什么关系?

浅谈ASP.NET内部机制(六)

前言:大家都听说过也用过ASP.NET中的视图ViewState,到底ViewState本质上到底是什么东西?为什 么ASP.NET中没有他不行?下面就来谈谈... 我们一般在开发面向对象程序的时候,我们都是用对象保存数据的,比如用对象的属性,字段来保存 对象的状态.当调用对象的方法时,就可以改变对象的状态.释放对象后,对象的状态就消失.这点大家 都熟悉.在开发桌面程序的时候,没有什么问题,以为对象都一般在本地的内存中,直到不再用那个对象 ,我们就销毁它.但是在Web程序中,问题就大了,比如我们

如何通过Oracle的缓冲区内部机制调整性能

在本篇Oracle高级教程里,我会探讨Oracle数据缓冲区的内部机制--Oracle用这一内存来防止不必要的数据块从磁盘重读.理解Oracle数据缓冲区如何操作,是成功地运用它们调整数据库性能的关键. 在Oracle 8i以前的版本里,当数据块被从磁盘送进数据缓冲区的时候,数据块会被自动地放置到最近使用过的数据列表的前部.但是,这种行为从Oracle 8i开始就变了:新数据缓冲区被放置在缓冲区链的中部.在调节数据库的时候,你的目标就是为数据缓冲区分配尽量多的内存,而不会导致数据库服务器在内存里

Ajax的错误处理机制探讨(2)

ajax|错误|错误处理 实际的例子:把客户端错误传递到服务器上 现在我们知道了XMLHttpRequest和JavaScript错误处理的一些基础知识了,我们来看一个同时使用了两者的实现例子.你可能认为JavaScript错误可以很简单地在流行的"黄色死亡三角"中显示出来,但是仍然有一些错误传递到了几家篮筹股公司的公共web站点的质量部门了. 因此,我将提供一个用于捕捉错误并把错误记录到服务器上的方法,这样其他人就可能修补这些问题.首先,我们考虑客户端.客户端必须提供一个类,它被用作

总是出现HTTP错误500.100内部服务器错误ASP错误解决

错误|服务器|解决|内部服务器     问:当调试程序出错的时候,为什么有的机器总是出现"HTTP 错误 500.100 - 内部服务器错误 - ASP 错误",而不能显示具体的出错信息? 原因: IE浏览器设置中屏蔽掉了出错的具体信息. 解决: 1.选择IE浏览器--工具--Internet选项. 2.在高级选项框中将"显示友好HTTP错误信息"的勾选去掉.

Microsoft SQL Server 查询处理器的内部机制与结构

摘要:本文介绍了在客户机上处理 Microsoft SQL Server 查询的方式,各种客户机与 SQL Server 的交互方式,以及 SQL Server 在处理客户机程序的请求时需要完成的工作. 简介 Microsoft(R) SQL Server(TM) 内部机制和结构是一个非常大的主题,因此本文仅限于程序开发人员感兴趣的问题,集中研究其他源中没有彻底讨论的问题.在讨论 SQL Server 的结构时,我们主要观察客户机的处理过程,研究不同的客户机程序与 SQL Server 的交互方