您好,欢迎访问一九零五行业门户网

jQuery1.9.1源码分析系列(十六)ajax之ajax框架_jquery

ajax 简介
ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
您应当具备的基础知识
在继续学习之前,您需要对下面的知识有基本的了解:
html / xhtml
css
javascript / dom
如果您希望首先学习这些项目,请在我们的首页访问这些教程。
什么是 ajax ?
ajax = 异步 javascript 和 xml。
ajax 是一种用于创建快速动态网页的技术。
通过在后台与服务器进行少量数据交换,ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 ajax)如果需要更新内容,必需重载整个网页面。
有很多使用 ajax 的应用程序案例:新浪微博、google 地图、开心网等等。
google suggest
在 2005 年,google 通过其 google suggest 使 ajax 变得流行起来。
google suggest 使用 ajax 创造出动态性极强的 web 界面:当您在谷歌的搜索框输入关键字时,javascript 会把这些字符发送到服务器,然后服务器会返回一个搜索建议的列表。
今天就开始使用 ajax
ajax 基于已有的标准。这些标准已被大多数开发者使用多年。
既然是ajax框架,那么闲谈一谈jquery的ajax处理思路。
现在的浏览器都支持ajax,只不过不同的浏览器使用方法可能有不同(ie使用new window.activexobject(microsoft.xmlhttp),标准浏览器使用new window.xmlhttprequest())。如果按照这种思路,貌似jqajax只需要做好兼容处理就行了?
不是的,原生的ajax有一个说大不大说小不小的缺点——不支持跨域(同源策略由来已久,自行百度)。所以jqajax添加了这方面的处理,jqajax是如何解决跨域问题的?
http://img2.imgtn.bdimg.com/it/u=2406301718,2822592556&fm=21&gp=0.jpg/>
是能取到图片的,很明显图片的路径和你的服务端不是一个域的。你可以试试看所有的带有src属性的标签都不受同源策略的影响。所以,jquery就使用了这个属性,对于跨域请求使用script标签的src来请求路径。
然后jquery在加上对ajax事件的三种监听方式:
1.全局事件:$(document).on(‘ajaxstart',func);
2.ajax设置回调项:$.ajax({url: php.html, complete: func });
3.deferred绑定方式:$.ajax(…).done(func);
基本上这就是jqajax所做的事情。
在正真进入ajax框架核心之前,先来分析一jquery准备的几个序列化提交表单的函数。
a. 表单序列化
所谓的表单序列化即将表单需要提交的内容组成类似:“key=value&key=value…”形式的字符串。
序列化用到三个函数:
jquery.fn. serialize()(序列化函数,筛选出表单中需要提交的数据并以序列化字符串方式返回,形如:“key=value&key=value…”)
jquery.fn. serializearray()(筛选出表单中需要提交的数据并以key/value键值对的对象数组格式返回,返回[{name:'key',value:'select1'},{name:'selectm',value:'selectm1'}, {name:'selectm',value:'selectm2'}, { name:'key2',value:0}…])
jquery.param(serializearray, traditional )(将key/value键值对的对象数组序列化为“key=value&key=value…”字符串)。
serialize直接调用jquery.param( this.serializearray() )即可。
serializearray的源码如下:主要进行三个步骤:提取表单元素、过滤出满足提交条件的表单元素、组合成key/value键值对的对象数组
serializearray: function() { //将form中的表单相关的元素取出来组成数组 return this.map(function(){ //表单节点有elements这个特征 var elements = jquery.prop( this, elements ); return elements ? jquery.makearray( elements ) : this; }) //过滤出为需要提交的表单元素(有name名称、非disabled元素、非提交按钮等元素、checkbox/radio的checked的元素) .filter(function(){ var type = this.type; //使用.is(:disabled)过滤掉不可用的表单元素 return this.name && !jquery( this ).is( :disabled ) && rsubmittable.test( this.nodename ) && !rsubmittertypes.test( type ) && ( this.checked || !manipulation_rcheckabletype.test( type ) ); }) //将表单提交元素组成name和value的对象数组 .map(function( i, elem ){ var val = jquery( this ).val(); return val == null ? null : jquery.isarray( val ) ? jquery.map( val, function( val ){ return { name: elem.name, value: val.replace( rcrlf, \r\n ) }; }) : { name: elem.name, value: val.replace( rcrlf, \r\n ) }; }).get();}
需要注意的是jquery的过滤结果符合正常的表单提交结果://过滤出为需要提交的表单元素(有name名称、非disabled元素、非提交按钮等元素、checkbox/radio的checked的元素)
param函数源码如下:主要进行两个处理:将key/value成作为uri组件编码(保证key和value不会出现特殊符号,即保证了“=”分割的正确性)、使用“&”链接并将空白符被替换成了+
jquery.param = function( a, traditional ) { var prefix, s = [], add = function( key, value ) { //如果value是函数,执行他得到真正的value value = jquery.isfunction( value ) ? value() : ( value == null ? : value ); //把key和value作为uri组件编码,保证key和value不会出现特殊符号,即保证了“=”分割的正确性 s[ s.length ] = encodeuricomponent( key ) + = + encodeuricomponent( value ); }; ... //传入的是数组,假设他是一个form表单键值对数组 if ( jquery.isarray( a ) || ( a.jquery && !jquery.isplainobject( a ) ) ) { //序列化表单元素 jquery.each( a, function() { add( this.name, this.value ); }); } else { ... } //返回序列化结果,注意:空白符被替换成了+ return s.join( & ).replace( r20, + );};
其中encodeuricomponent详细点击查看
b. ajax的事件监听
给ajax绑定事件有三种方式
1.全局事件:$(document).on(‘ajaxstart',func);
2.ajax设置回调项:$.ajax({url: php.html, complete: func });
3.deferred绑定方式:$.ajax(…).done(func);
接下来我们一一讲解他们的实现。
全局事件(ajaxstart/ajaxstop/ajaxcomplete/ajaxerror/ajaxsuccess/ajaxsend)
使用.on事件绑定这种通用方式我们毫无疑问是可以绑定ajax监听事件,除此之外还可以直接使用$(…).ajaxstart(func)来绑定事件。他们的实现也是用.on来绑定。
jquery.each( [ ajaxstart, ajaxstop, ajaxcomplete, ajaxerror, ajaxsuccess, ajaxsend ], function( i, type ){ jquery.fn[ type ] = function( fn ){ return this.on( type, fn ); };});
触发事件比较简单,在进行ajax处理过程中在合适的时机直接使用jquery.event.trigger直接触发。以ajaxstart为例
//如果此时没有正在执行的请求,则触发ajaxstart事件 if ( fireglobals && jquery.active++ === 0 ) { jquery.event.trigger(ajaxstart); }  
ajax设置回调项(beforesend/complete/success/error)
触发设置回调项分两种:beforesend直接在适当的时机调用。源码
//调用beforesend回调,如果回调返回失败或abort则返回中止if ( s.beforesend && ( s.beforesend.call( callbackcontext, jqxhr, s ) === false || state === 2 ) ) { //中止如果没有准备好 return jqxhr.abort(); } complete/success/error则利用deferred的特性将回调添加到延时队列,等待延时状态处理。源码//创建最终选项对象s = jquery.ajaxsetup( {}, options )...deferred = jquery.deferred(),completedeferred = jquery.callbacks(once memory),...//添加延时事件deferred.promise( jqxhr ).complete = completedeferred.add;jqxhr.success = jqxhr.done;jqxhr.error = jqxhr.fail;//安装回调到deferreds上for ( i in { success: 1, error: 1, complete: 1 } ) {jqxhr[ i ]( s[ i ] );}//在ajax请求完成的处理函数中执行completedeferred的延时列表function done(){...//执行complete处理completedeferred.firewith( callbackcontext, [ jqxhr, statustext ] );...}
deferred方式绑定回调
deferred方式绑定事件就不用特别说明了,因为ajax本身就是一个延时对象。直接使用$.ajax(…).done(fn).fail(fn). progress(fn).always(fn).then(fn)。源码
deferred = jquery.deferred(),completedeferred = jquery.callbacks(once memory),...deferred.promise( jqxhr ).complete = completedeferred.add;...return jqxhr;
其它类似信息

推荐信息