jQuery ajax —— 一些细节以及主函数扩展出来

系统 2476 0

上一篇文章 ,讲解了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"
      
         );
}
      
    

 

 

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


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论