jQuery ajax源码解析

  • 格式:doc
  • 大小:62.50 KB
  • 文档页数:21

7.1 jquery的ajax常用方法对于Ajax原理不深入分析。

Jquery肯定也会提供Ajax的实现。

对于ajax的请求,可以分成如下的几步:1、通过new XMLHttpRequest 或其它的形式(指IE)生成ajax的对象xhr。

2、通过xhr.open(type, url, async, username, password)的形式建立一个连接。

3、通过setRequestHeader设定xhr的请求头部(request header)。

4、通过send(data)请求服务器端的数据。

5、执行在xhr上注册的onreadystatechange回调处理返回数据。

任何的lib都是在这几步之上进行相关扩展而达到自己的功能。

这几步之中,对于url,我们要考虑是跨域请求怎么办,ajax为了安全的考虑不支持跨域请求,那么对于这个问题,Jquery和Ext都是采用scriptTag的方式。

Jquery主要就是解决上面这问题,之后就在这个基础之上进行扩展,如getScript,getJ son之类的函数。

Ajax一个很重要的任务就是提交form。

Jquery Ajax提供了如Prototype 的form中serializeElements把form的元素串行起请求字符串。

这是ajax的辅助方法。

对于ajax的应用,不管对返回的数据进行如何的处理,其最终目的还是得落在页面的显示上,也是某一个或一些dom元素上。

那么我从这个需要改变内容的dom元素(集合)出发,通过ajax去获得数据进行一些处理最终填充到给定的元素中。

这和prototype中Aj ax.Updata相似。

loadJquery对象的load(url, params, callback)函数就是完成这类似的工作的。

上面的代码①可以看出load的url参数可以指定选择符,来筛选载入的HTML 文档,D OM 中将仅插入筛选出的HTML 代码。

语法形如"url #some > selector"。

在④处通过h tml的方式插入到元素的内部(取代)。

其支持的response应该是html的片断。

param在②处通过调用了jQuery.param(params)来完成对params的key/value的对象形式转换成查寻字符串的形式。

Get&postLoad有的时候也不能很好地完成功能,如果不是html的response。

那么不能采用了。

Jquery还提供了几个静态方式:jquery.get()、jquery. getScript ()、jquery. getJSON ()、jquery. post ()。

jquery. getScript ()、jquery. getJSON ()不过是在jquery.get()基础之上提供了某方面的简单的处理。

Get和Post在这里没有什么不一样,除了请求的type不一样之外。

Get和post都是在ajax的请求方面没有什么区别。

除了在服务器的接收处理的方面有所不同之外。

如get在.net中是request.querstring,而post则是采用request.form来获得。

getScript、getJSON都是在调用jQuery.get,传入不同的datatype的形式来区别不同的类型。

7.2 jquery.ajax这所有的最终都是通过jQuery.ajax()来完成的。

Jquery.ajax是大包大揽的非常复杂的一个方法。

它并没有像其它的lib一样,把每个小部分都分开来。

它是整个都整在一个函数中。

看起来很多,实际上上也没有脱离前面所说的a jax的请求的五步。

它的很大一部分代码在处理跨域请求的处理上。

下面就分别就ajax的代码进行分析。

ajaxSettings在①处通过继承的方式把传入参数s和默认的jQuery.ajaxSettings都clone到s变量中。

S的同名属性会覆盖jQuery.ajaxSettings的同名属性。

这里两次继承s,以便在测试中能检测。

这是默认的ajax的设定,我们要在参数s设定同名的属性来覆盖这些属性。

但是我们不能覆盖accepts。

这个会在后面的代码用到。

我们可以通过设定s.dataType等于accept s中的某一个属性key指定请求的data类型,如xml,html,script,json,text。

dataType还支持默认的_default和跨域的jsonp。

不过其最终会解析成script。

scriptTag②~⑥是处理跨域请求的部分。

对于dataType为jsonp的类型,给其请求的字符串(可能是s.data)加上callback=callbackfn的key/value串,然后在window下注册一个callbackfn的函数。

这个函数的形式如callbackfn(data){ data = tmp;success();complete();}。

它代理了通过ajax(s)的传入s参数中success();complete()的功能。

它就是调用这个函数,实际上是调用success();complete()的函数。

那么怎么调用呢?ajax不支持跨域。

在⑤处,我们可以看到这里是采用scriptTag的方式来完成。

先在页面的<head>中添加一个<script src=url />的标签。

因为在<head>中。

浏览器会自动载入并运行请求返回的script。

如果是jsonp的形式,服务器端还要动态生成的content-type为script的代码:callbackfn(data);只有这样才会调用在window中注册的函数callbackfn。

同时传入所需要的参数。

如dataType == "script"形式的跨域,那只能是通过script.onload 或script.onreadystatechange事件来触发回调。

这里我们可以通过服务器返回的script代码:var data=xxx。

来传递参数给s.success();plete()。

Jquery 这里采用是全局变量data来进行操作的。

Ajax Event④是采用了jQuery.event.trigger("ajaxStart");来触发全局的ajaxStart事件。

这也是说只要注册了这个事件的元素,在任何的ajax的请求时ajaxStart都会执行元素注册的事件处理函数。

这和Ext的事件有点相似。

但是它不是全局的。

jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,aj axSend".split(","), function(i, o) {jQuery.fn[o] = function(f) {// f:functionreturn this.bind(o, f);};上面的代码是为jquery对象注册了ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSucc ess,ajaxSend这几种ajax的事件方法,在jquery.ajax中不同的时刻都会触发这些事件。

当然我们也可以采用s.global=false来设定不触发这些事件。

因为这是全局的,个人认为其设计的目的就是为了在这些时候能以某种形式来告诉用户ajax的进行的状态。

如在ajaxstart的时候,我们可能通过一个topest的div层(加上遮罩的效果)的元素注册一个ajaxstart事件的处理方法。

该方法就是显示这个层和显示“你的数据正在提交。

”这个的提示。

这是这6种事件的最佳用法了。

如果进行私有处理,那么要在事件的处理函数中进行判断。

因为每个事件处理函数的第二参数是jquery.ajax(s)的s参数。

我们可以在这个参数中做私有的标识,如eventType:xx x。

每类不同的请求有不同的eventType值。

在事件处理函数再根据这个eventType==xxx 进行判断,从而进行私有的处理。

如果有大量的这样的私有处理也是会影响ajax的效率的。

setRequestHeader⑥处是创建一个xhr对象并通过open来创建一个连接(socket)。

⑦处是设定请求的头部(setRequestHeader)。

如果data的存在的话,那就得设定Cont ent-Type,便于服务器按一定的规则来解码。

可以看出post的方式通过data传递数据要安全一点。

那么服务器如果区别这个请求是ajax呢?因为同步和异步ajax的请求的头文件是一样的。

我们如果通过X-Requested-With"="XMLHttpRequest”来标识这个请求是ajax的请求。

如果服务器硬是要区分的话,就可以通过获取该头部来判断。

在头部的定义中,还可能通过Accept来指定接受的数据的类型,如application/xml, t ext/xml", "text/html", "text/javascript, 等等。

头部还有一个If-Modified-Since的属性用来提高效率的。

它和”Last-Modified配合起来使用。

在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间,格式类似这样:Last-Modified: Fri, 12 May 2006 18:53:33 GMT客户端第二次请求此URL时,根据HTTP 协议的规定,浏览器会向服务器传送If-Mo dified-Since 报头,询问该时间之后文件是否有被修改过:If-Modified-Since: Fri, 12 Ma y 2006 18:53:33 GMT如果服务器端的资源没有变化,则自动返回HTTP 304 (Not Changed.)状态码,内容为空,这样就节省了传输数据量。

当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求时类似。

从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。

拦截处理⑧处是一个send之前的拦截处理,可以通过s. beforeSend(xhr, s)函数的形式传入拦截函数。

保证在发送之前确保满足某些条件。

在取得返回数据的时候,也可以通过s.dataF ilter(data, type);形式来拦截处理data。

不过这里主要的作用对data进一步的筛选。