方法复制jQuery ajax —— 一些细节以及主函数扩展出来的方法

查了好多资料,发现还是不全,干脆自己整理吧,至少保证在我的做法正确的,以免误导读者,也是给自己做个记录吧!

    上一篇文章,讲授了jQuery.ajax函数。这篇文章将其他一些细节补充完。下一篇文章则开始讲授,jQuery是如何将script动态载入、XMLHttpRequest、JSONP一同包装进jQuery.ajax里的。

 

    

jQuery.ajaxSetup

    我们可以从主函数看出,参数是通过jQuery.ajaxSetup发生的:

    

    //

    通过jQuery.ajaxSetup改造参数对象

    s =

    jQuery.ajaxSetup( {}, options ),

    

    那么jQuery.ajaxSetup在干些什么呢?

jQuery.ajaxSetup = function( target, settings ) {
    // 如果有参数
    return settings ?

        // 创立一个设置对象,先将jQuery.ajaxSettings的属性放进去,
        // 然后将参数也放进去
        ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :

        // 并将设置对象的属性放进jQuery.ajaxSettings对象里
        ajaxExtend( jQuery.ajaxSettings, target );
};
 

    

ajaxExtend

    ajaxExtend和jQuery.extend有一些不同,避免有些不需要深复制的属性进行深复制。

function ajaxExtend( target, src ) {
    var key, deep,
        flatOptions = jQuery.ajaxSettings.flatOptions || {};
    
    // 遍历src对象中的所有key
    for ( key in src ) {
        // 如果值不是undefined
        if ( src[ key ] !== undefined ) {
            // 判断是否是不需要深复制的,如果不需要深复制,将属性直接写进target,
            // 否则写进deep里存起来
            // 我们可以从jQuery.ajaxSettings.flatOptions看到,
            // 现实上不需要深复制的是url和context
            ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
        }
    }
    
    // 如果deep不是undefined,证明需要深复制
    if ( deep ) {
        // 开始深复制
        jQuery.extend( true, target, deep );
    }

    // 返回target
    return target;
}
 

    

ajaxHandleResponses

    主体函数中response是通过ajaxHandleResponses来处理的:

    

    //

    失掉响应数据

    if

    ( responses ) {

    //

    通过ajaxHandleResponses处理数据

    response =

    ajaxHandleResponses( s, jqXHR, responses );}

    

    我们来看看该函数干了些什么。

function ajaxHandleResponses( s, jqXHR, responses ) {

    var ct, type, finalDataType, firstDataType,
        contents = s.contents,
        dataTypes = s.dataTypes,
        responseFields = s.responseFields;

    // 将responseXXX填入jqXHR指定位置,也就是responseXML或者responseText
    // 其中jqXHR.xml对应responseXML,jqXHR.text对应responseText
    for ( type in responseFields ) {
        if ( type in responses ) {
            jqXHR[ responseFields[type] ] = responses[ type ];
        }
    }

    // 删撤除通配dataType,失掉返回的Content-Type
    while( dataTypes[ 0 ] === "*" ) {
        dataTypes.shift();
        if ( ct === undefined ) {
            ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
        }
    }

    // 看看是否是我们能处理的Content-Type,比如图片这类二进制类型就不好处理了
    if ( ct ) {
        // 现实上能处理的就是text、xml和json
        for ( type in contents ) {
            if ( contents[ type ] && contents[ type ].test( ct ) ) {
                // 如果是这三种类型,则推入dataTypes里
                dataTypes.unshift( type );
                break;
            }
        }
    }

    // 如果dataTypes是我们想要的,也就是text、xml、json
    if ( dataTypes[ 0 ] in responses ) {
        // 则终究dataType就是这个了
        finalDataType = dataTypes[ 0 ];
    // 否则
    } else {
        // 实验转换成我们要的dataType
        for ( type in responses ) {
            // 如果dataTypes[ 0 ]不存在,则直接用type作为终究dataType
            // 否则,看看能不能转换,能的话就用type作为终究dataType
            if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
                finalDataType = type;
                break;
            }
            // 保存第一个type
            if ( !firstDataType ) {
                firstDataType = type;
            }
        }
        // 用终究dataType或者用第一个type
        finalDataType = finalDataType || firstDataType;
    }

    // 如果有终究dataType
    if ( finalDataType ) {
        // 如果终究dataType不是dataTypes[ 0 ]
        if ( finalDataType !== dataTypes[ 0 ] ) {
            // 将finalDataType推入dataTypes队列里
            dataTypes.unshift( finalDataType );
        }
        // 返回responses对应的finalDataType数据
        return responses[ finalDataType ];
    }
}
    每日一道理
航行者把树比作指引方向的路灯,劳动者把树比作遮风挡雨的雨伞,诗人把树比作笔下的精灵,而我却要把树比作教师,它就是为我们遮风挡雨的伞,指明方向的路灯,打开知识殿堂的金钥匙。
 

    

jQuery.fn.load

    现实上有两个jQuery.fn.load,一个是类似于onload的方法,另一个则是载入指定html页面。

    前一个是jQuery.fn.on的简单扩展,而前面一个则是应用jQuery.ajax方法的扩展。

jQuery.fn.load = function( url, params, callback ) {
    // 如果url不是string,且_load存在
    // 证明这是onload方法,则调用保存的_load方法
    if ( typeof url !== "string" && _load ) {
        return _load.apply( this, arguments );
    }

    var selector, type, response,
        self = this,
        off = url.indexOf(" ");

    // 看看是否是载入指定元素,比如参数是'ajax/test.html #container'
    if ( off >= 0 ) {
        // 分隔出需要载入的元素
        selector = url.slice( off, url.length );
        // 分隔出真正的url
        url = url.slice( 0, off );
    }

    // 模拟重载
    if ( jQuery.isFunction( params ) ) {

        // 如果是函数那么就当这个是回调函数
        callback = params;
        params = undefined;

    // 如果参数是objects,那么定义type是POST
    } else if ( params && typeof params === "object" ) {
        type = "POST";
    }

    // 如果有需要修改的元素,开始请求
    if ( self.length > 0 ) {
        jQuery.ajax({
            url: url,

            // 如果type为undefined,那么就会缺省为GET方法
            type: type,
            dataType: "html",
            data: params
            // 完成后回调
        }).done(function( responseText ) {

            // 保存reponse
            response = arguments;

            // 对元素写入html
            // 如果selector存在
            self.html( selector ?

                // 先用一个div来存储整个html页面的DOM,在找到selector的相关html
                jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :

                // 否则直接用responseText
                responseText );

            // 如果回调函数存在,则回调
        }).complete( callback && function( jqXHR, status ) {
            self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
        });
    }

    return this;
};
 

    

jQuery.get & jQuery.post

    这两个方法现实上就是通过jQuery.ajax扩展而来的。

// 加上get和post方法
jQuery.each( [ "get", "post" ], function( i, method ) {
    // jQuery.get或jQuery.post为
    jQuery[ method ] = function( url, data, callback, type ) {
        // 模拟重载
        if ( jQuery.isFunction( data ) ) {
            type = type || callback;
            callback = data;
            data = undefined;
        }

        // 利用jQuery.ajax完成任务
        return jQuery.ajax({
            url: url,
            type: method,
            dataType: type,
            data: data,
            success: callback
        });
    };
});
 

    

jQuery.getScript & jQuery.getJSON

    jQuery.getScript和jQuery.getJSON则是由jQuery.get扩展而来的。

jQuery.getScript = function( url, callback ) {
    return jQuery.get( url, undefined, callback, "script" );
};
jQuery.getJSON = function( url, data, callback ) {
    return jQuery.get( url, data, callback, "json" );
}
 

 

文章结束给大家分享下程序员的一些笑话语录: 程序员打油诗   
  写字楼里写字间,写字间里程序员;
  程序人员写程序,又拿程序换酒钱。
  酒醒只在网上坐,酒醉还来网下眠;
  酒醉酒醒日复日,网上网下年复年。
  但愿老死电脑间,不愿鞠躬老板前;
  奔驰宝马贵者趣,公交自行程序员。
  别人笑我忒疯癫,我笑自己命太贱;
  不见满街漂亮妹,哪个归得程序员。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值