Ajax 原理

Ajax 原理作为一个技术人员 我看到一项新技术 总是喜欢琢磨琢磨它内部是如何实现的 在对 Ajax 有了初步认识以后 自然想看看其内部机制 但是令我失望的是 至少介绍 Ajax 内部实现的文章少之又少 好容易找到一篇 却也只是简单列了列一些 javascript 代码 并且没什么解释 颇为郁闷 想想求人不如求己 况且自己研究的或许印象更深一些 于是找到了一个 AjaxPro 下来琢磨琢磨 只是对于 JavaS

作为一个技术人员,我看到一项新技术,总是喜欢琢磨琢磨它内部是如何实现的。在对 Ajax 有了初步认识以后,自然想看看其内部机制,但是令我失望的是,至少介绍 Ajax 内部实现的文章少之又少,好容易找到一篇,却也只是简单列了列一些 javascript 代码,并且没什么解释,颇为郁闷。想想求人不如求己,况且自己研究的或许印象更深一些。于是找到了一个 AjaxPro,下来琢磨琢磨,只是对于 JavaScript 我实在知之甚少,不明白之处依然很多,不过还是想写出来,抛砖引玉,望高人们不吝指教。

   一、使用的例子

  本文使用的例子很简单,一个文本框,在其中敲入文字之后,下方就显示该文字并加上一个“(Hello from server)”。源码如下(有删节):

 1
Ajax 原理 <% @ Page language=c# ClassName=KeyPressDemo Inherits=System.Web.UI.Page  %>

 2 Ajax 原理 < script  runat =”server”  language =”c#” >

 3Ajax 原理

 4Ajax 原理private void Page_Load(object sender, EventArgs e)

 5Ajax 原理{


 6Ajax 原理    AjaxPro.Utility.RegisterTypeForAjax(typeof(KeyPressDemo));

 7Ajax 原理}


 8Ajax 原理

 9Ajax 原理[AjaxPro.AjaxMethod]

10Ajax 原理public string EchoInput(string s)

11Ajax 原理{


12Ajax 原理    return s +=  (Hello from server);

13Ajax 原理}


14Ajax 原理

15Ajax 原理

script >

16 Ajax 原理

17 Ajax 原理 < form  id =”Form1″  method =”post”  runat =”server” >
form >

18 Ajax 原理

19 Ajax 原理 < div  class =”content” >

20 Ajax 原理 < h1 > KeyPressDemo Examples
h1 >

21 Ajax 原理 < p > Press any key in the textbox and see the echo in the DIV element on the right side.
p >

22 Ajax 原理 < input  type =”text”  id =”myinput”  onkeyup =”doTest1();” />   < div  id =”mydisplay” > —- empty —-
div >

23 Ajax 原理 < p >< i > Note, that I do not update the display if a request is running currently.
i >
p >

24 Ajax 原理
div >

25 Ajax 原理

26 Ajax 原理 < script  type =”text/javascript”  defer =”defer” >

27Ajax 原理

28Ajax 原理var timer = null;

29Ajax 原理

30Ajax 原理function doTest1() {


31Ajax 原理    if(timer != null{


32Ajax 原理      clearTimeout(timer);

33Ajax 原理    }


34Ajax 原理    timer = setTimeout(doTest1_next, 100);

35Ajax 原理}


36Ajax 原理

37Ajax 原理function doTest1_next() {


38Ajax 原理    var ele = document.getElementById(myinput);

39Ajax 原理    ASP.KeyPressDemo.EchoInput(ele.value, doTest1_callback);

40Ajax 原理}


41Ajax 原理

42Ajax 原理function doTest1_callback(res) {


43Ajax 原理    var ele = document.getElementById(mydisplay);

44Ajax 原理    ele.innerHTML = res.value;

45Ajax 原理}


46Ajax 原理

47Ajax 原理

script >

  选用这个例子,是因为它比较简单,没有相关的 C# 文件。首先看看第17行,咦?怎么这个 form 里啥都没有?既然什么都没有?删掉它行不行?不行,绝对不行!看看网页打开后,这一行被扩展成了什么?

1
Ajax 原理 < form  name =”Form1″  method =”post”  action =”keypress.aspx”  id =”Form1″ >

2 Ajax 原理 < div >

3 Ajax 原理 < script  type =”text/javascript”  src =”/ajaxdemo/ajaxpro/core.ashx” >
script >

4 Ajax 原理 < script  type =”text/javascript”  src =”/ajaxdemo/ajaxpro/ASP.KeyPressDemo,App_Web_vxhzzzxr.ashx” >
script >

5 Ajax 原理
form >

6 Ajax 原理

  请注意这里链入的两个 javascript 文件,它们是 Ajax 得以运行的基础!删掉 form 那一行,它们就不会出现,自然不行了。这两行是如何产生的?那就是页面代码的第4至7行的 PageLoad 函数的功劳了。

  好,那这两个 javascript 文件我们能看到不?看上去它们是服务端的,并且事实上是服务端动态生成的。不过稍有些了解浏览器工作原理的人就会知道,到 Local Settings 下的 Temporary Internet Files 目录下去找,肯定是有的,因为浏览器下载页面的时候会把与页面相关的文件都下过来。

  二、Ajax ClientScript 的执行总体流程


  好,有了源页面代码,又有了两个 ClientScript 文件,我们就可以分析客户端的执行流程了。以下是我画的一张简单的流程图:

Ajax 原理

  我们一个一个地来分析。

  三、HTML页面做了什么?


  第一步,当我们在 TextBox 里输入字符后,将会触发 onkeyup 事件。它要执行 doTest1 方法。见页面代码里的第22行。

  第二步,doTest1 方法使用 setTimeout 函数,设定了 100 毫秒后,执行 doTest1_next 方法。见页面代码里的第34行。

  第三步,doTest1_next 方法调用了 ASP.KeyPressDemo.EchoInput 方法,它带有两个参数,第一个是我们在文本框中输入的值,当然是个字符串类型的了;第二个则是一个 callback 函数,请留心这个函数,它将于整个流程的最后执行。

  好,我们知道页面的客户端无外乎就是 HTML 和 JavaScript,虽然 ASP.KeyPressDemo.EchoInput 方法酷似页面里我们自己用 C# 写的函数,但可以肯定的是它绝对是用 JavaScript 实现的。在哪儿呢?嗯,在我们从 Temporary Internet Files 目录下找到的 ASP.KeyPressDemo,App_Web_vxhzzzxr.ashx 里。

   四、ASP.KeyPressDemo,App_Web_vxhzzzxr.ashx 的实现


  这个文件很小,以下是它的全部源码:

 1
Ajax 原理 addNamespace( ASP );

 2 Ajax 原理ASP.KeyPressDemo_class  =  Class.create();

 3 Ajax 原理ASP.KeyPressDemo_class.prototype  =  ( new  AjaxPro.Request()).extend( {


 4Ajax 原理    EchoInput: function(s, callback) {


 5Ajax 原理        return this.invoke(EchoInput{
s:s}
, callback);

 6Ajax 原理    }
,

 7Ajax 原理    initialize: function() {


 8Ajax 原理        this.url = /ajaxdemo/ajaxpro/ASP.KeyPressDemo,App_Web_vxhzzzxr.ashx;

 9Ajax 原理    }


10Ajax 原理}
)

11 Ajax 原理ASP.KeyPressDemo  =   new  ASP.KeyPressDemo_class();

12 Ajax 原理

  啊哈,这下我们知道了,ASP.KeyPressDemo 其实是在这里用 JavaScript 定义的 ASP.KeyPressDemo_class 类的实例,EchoInput 则是它的一个方法。注意一下每3行,我们看到这个类是从 AjaxPro.Request 类继承的。什么什么?继承?有没有搞错?JavaScript 什么时候开始面向对象了而不是基于对象了?先摆下这个疑问,我们继续往下看。

  EchoInput 方法的实现很简单,就是调用了一个 Invoke 方法。嗯,这个方法想必是从 AjaxPro.Request 类“继承”下来的。那它定义在哪儿?是了,还有一个 core.ashx 呢,它才是真正客户端实现 Ajax 技术的主角!这个文件太大,我们还是依照函数调用顺序慢慢来拆解罢。

  五、Invoke 函数

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

 1
Ajax 原理 AjaxPro.Request  =  Class.create();

 2 Ajax 原理AjaxPro.Request.prototype  =  ( new  AjaxPro.Base()).extend( {


 3Ajax 原理    invoke: function(method, data, callback) {


 4Ajax 原理        var async = typeof callback == function && callback != AjaxPro.noOperation;

 5Ajax 原理        var json = AjaxPro.toJSON(data) + /r/n;

 6Ajax 原理

 7Ajax 原理        if(AjaxPro.cryptProvider != null)

 8Ajax 原理            json = AjaxPro.cryptProvider.encrypt(json);

 9Ajax 原理

10Ajax 原理        this.callback = callback;

11Ajax 原理

12Ajax 原理        if(async) {


13Ajax 原理            this.xmlHttp.onreadystatechange = this.doStateChange.bind(this);

14Ajax 原理            if(typeof this.onLoading == functionthis.onLoading(true);

15Ajax 原理        }


16Ajax 原理            

17Ajax 原理        this.xmlHttp.open(POSTthis.url, async);

18Ajax 原理        this.xmlHttp.setRequestHeader(Content-Typeapplication/x-www-form-urlencoded);

19Ajax 原理        this.xmlHttp.setRequestHeader(Content-Length, json.length);

20Ajax 原理        this.xmlHttp.setRequestHeader(Ajax-method, method);

21Ajax 原理        

22Ajax 原理        if(AjaxPro.token != null && AjaxPro.token.length > 0)

23Ajax 原理            this.xmlHttp.setRequestHeader(Ajax-token, AjaxPro.token);

24Ajax 原理

25Ajax 原理        if(MS.Browser.isIE)

26Ajax 原理            this.xmlHttp.setRequestHeader(Accept-Encodinggzip, deflate);

27Ajax 原理        else

28Ajax 原理            this.xmlHttp.setRequestHeader(Connectionclose);    // Mozilla Bug #246651

29Ajax 原理

30Ajax 原理        if(this.onTimeout != null && typeof this.onTimeout == function)

31Ajax 原理            this.timeoutTimer = setTimeout(this.timeout.bind(this), this.timeoutPeriod);

32Ajax 原理

33Ajax 原理        this.xmlHttp.send(json);

34Ajax 原理        

35Ajax 原理        json = null;

36Ajax 原理        data = null;

37Ajax 原理        delete json;

38Ajax 原理        delete data;

39Ajax 原理        

40Ajax 原理        if(!async) {


41Ajax 原理            return this.createResponse();

42Ajax 原理        }


43Ajax 原理        

44Ajax 原理        return true;    

45Ajax 原理    }


46Ajax 原理}
);

47 Ajax 原理

  六、解释“继承”



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

1
Ajax 原理 Object.extend  =   function (destination, source)  {


2Ajax 原理    for(property in source) {


3Ajax 原理        destination[property] = source[property];

4Ajax 原理    }


5Ajax 原理    return destination;

6Ajax 原理}


7 Ajax 原理

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

1
Ajax 原理 initialize:  function (url)  {


2Ajax 原理    this.xmlHttp = new XMLHttpRequest();

3Ajax 原理}


4 Ajax 原理

  是了,xmlHttp 只是 XMLHttpRequest 的一个实例。那么 XMLHttpRequest 的定义呢?

 1
Ajax 原理 var  lastclsid  =   null ;

 2 Ajax 原理 if ( ! window.XMLHttpRequest)  {


 3Ajax 原理

 4Ajax 原理    function getXmlHttp(clsid) {


 5Ajax 原理        var xmlHttp = null;

 6Ajax 原理        try {


 7Ajax 原理            xmlHttp = new ActiveXObject(clsid);

 8Ajax 原理            lastclsid = clsid;

 9Ajax 原理            return xmlHttp;

10Ajax 原理        }
 catch(ex) {}

11Ajax 原理    }


12Ajax 原理    

13Ajax 原理    window.XMLHttpRequest = function() {


14Ajax 原理        if(lastclsid != null{


15Ajax 原理            return getXmlHttp(lastclsid);

16Ajax 原理        }


17Ajax 原理    

18Ajax 原理        var xmlHttp = null;

19Ajax 原理        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];

20Ajax 原理

21Ajax 原理        for(var i=0; i<clsids.length && xmlHttp == null; i++{


22Ajax 原理            xmlHttp = getXmlHttp(clsids[i]);

23Ajax 原理        }


24Ajax 原理        

25Ajax 原理        if(xmlHttp == null{


26Ajax 原理            return new IFrameXmlHttp();

27Ajax 原理        }


28Ajax 原理

29Ajax 原理        return xmlHttp;

30Ajax 原理    }


31Ajax 原理}


32 Ajax 原理
 1
Ajax 原理 doStateChange:  function ()  {


 2Ajax 原理    if(this.onStateChanged != null && typeof this.onStateChanged == function)

 3Ajax 原理        trythis.onStateChanged(this.xmlHttp.readyState); }catch(e){}

 4Ajax 原理

 5Ajax 原理    if(this.xmlHttp.readyState != 4)

 6Ajax 原理        return;

 7Ajax 原理

 8Ajax 原理    if(this.xmlHttp.status == 200{


 9Ajax 原理        if(this.timeoutTimer != null) clearTimeout(this.timeoutTimer);

10Ajax 原理        if(typeof this.onLoading == functionthis.onLoading(false);

11Ajax 原理

12Ajax 原理        this.xmlHttp.onreadystatechange = AjaxPro.noOperation;

13Ajax 原理

14Ajax 原理        this.callback(this.createResponse());

15Ajax 原理        this.callback = null;

16Ajax 原理

17Ajax 原理        this.xmlHttp.abort();

18Ajax 原理    }


19Ajax 原理}
,

20 Ajax 原理
 1
Ajax 原理 createResponse:  function ()  {


 2Ajax 原理    var r = new Object();

 3Ajax 原理    r.error = null;

 4Ajax 原理    r.value = null;

 5Ajax 原理

 6Ajax 原理    var responseText = new String(this.xmlHttp.responseText);

 7Ajax 原理

 8Ajax 原理    if(AjaxPro.cryptProvider != null && typeof AjaxPro.cryptProvider == function)

 9Ajax 原理        responseText = AjaxPro.cryptProvider.decrypt(responseText);

10Ajax 原理

11Ajax 原理    eval(r.value =  + responseText + ;);

12Ajax 原理

13Ajax 原理    if(r.error != null && this.onError != null && typeof this.onError == function)

14Ajax 原理        trythis.onError(r.error); }catch(e){}

15Ajax 原理

16Ajax 原理    responseText = null;

17Ajax 原理

18Ajax 原理    return r;

19Ajax 原理}











































版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/222571.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午3:29
下一篇 2026年3月17日 下午3:29


相关推荐

  • Hibernate二级缓存的使用「建议收藏」

    Hibernate二级缓存的使用「建议收藏」一、Hibernate共有两级缓存        Session级别缓存—-一级缓存(事务范围)        SessionFactory级别缓存—-二级缓存(进程范围) SessionFactory级别缓存        内置:Hibernate自带的,不可卸载.通常在Hibernate的初始化阶段,Hibernate会把映射

    2022年5月23日
    38
  • 使用git新建分支推送项目

    使用git新建分支推送项目前言 一个还在努力的编程小白转载请标注来源 git 分支操作一 新建自己的分支二 推送项目到仓库三 错误四 参考一 新建自己的分支如果单纯的提交分支 不用 pull 原来其他人的分支首先在项目文件上进行 git 初始化 gitinit 出现该文件说明初始化成功然后我们去 github 获取项目仓库 http 连接 gitremoteadd 你的 http 查看本地的连接 gitremote v 首先创建分支 gitcheckout b

    2026年3月16日
    2
  • myeclipse 序列号

    myeclipse 序列号

    2021年4月22日
    200
  • django url标签_正确的url格式

    django url标签_正确的url格式前言当我们访问网页的时候,后台返回列表中有n条数据,此时我们会使用分页,比如一页只展示10条,但是我们访问第一页的时候大多数情况下,都会给url一个默认值,访问的时候直接展示第一页数据案例我们的

    2022年7月28日
    8
  • mysqlnavicat连接不上_navicat打开连接报错

    mysqlnavicat连接不上_navicat打开连接报错前提,解压版MySQL问题描述,Navicat可以连接远程数据库,但是连接本地数据库时报10038解决方式,百度说,查看服务是否启动,但是打开我的服务根本就没有看到MySQL字样。我的解决方式是,用系统管理员启动cmd.exe,然后运行mysqldinstallMySQL,提示服务提示成功后,执行netstartmysql重新启动MySQL。再Navicat连接本地连接,连接成…

    2022年10月13日
    2
  • 世界坐标系,相机坐标系和图像坐标系的转换(Python)

    世界坐标系,相机坐标系和图像坐标系的转换(Python)世界坐标系 相机坐标系和图像坐标系的转换 Python 相机内参外参说明 https panjinquan blog csdn net article details 计算机视觉 相机成像原理 世界坐标系 相机坐标系 图像坐标系 像素坐标系之间的转换 https blog csdn net chentravelli article details

    2026年3月19日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号