首页 > 网站 > WEB开发 > 正文

jQuery-1.9.1源码分析系列(十六)ajax——ajax处理流程以及核心函数

2024-04-27 15:03:04
字体:
来源:转载
供稿:网友

  先来看一看jQuery的Ajax核心处理流程($.ajax)

a. ajax( [url,] options )执行流程


  第一步,为传递的参数做适配。url可以包含在options中

//传递的参数只是一个对象if ( typeof url === "object" ) {    options = url;    url = undefined;}//options强制转成对象options = options || {};

  第二步,创建一些变量,比较重要的是:创建最终选项对象s、全局事件上下文是callbackContext、创建deferred和completeDeferred、创建jqXHR对象。

var //跨域检测变量    parts,    ...    //创建最终选项对象    s = jQuery.ajaxSetup( {}, options ),    //回调上下文    callbackContext = s.context || s,    //全局事件上下文是callbackContext,如果他是一个DOM节点或jQuery集合(对象)    globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?    jQuery( callbackContext ) :    jQuery.event,    // Deferreds    deferred = jQuery.Deferred(),    completeDeferred = jQuery.Callbacks("once memory"),    ...    jqXHR = {        readyState: 0,        //建立请求头哈希表        getResponseHeader: function( key ) {...},        // Raw string        getAllResponseHeaders: function() {...},        //缓存请求头        setRequestHeader: function( name, value ) {...},        //重写响应content-type头        overrideMimeType: function( type ) {...},        //取决于状态的回调        statusCode: function( map ) {...},        //取消请求        abort: function( statusText ) {...}    };//添加延时事件deferred.PRomise( jqXHR ).complete = completeDeferred.add;jqXHR.success = jqXHR.done;jqXHR.error = jqXHR.fail;

  第三步,检查是否跨域。其中需要注意的是ajaxLocParts在jQuery初始化的时候就定义了

//rurl = /^([/w.+-]+:)(?:////([^//?#:]*)(?::(/d+)|)|)///需要注意的是本地文件一般形如"file:///C:/Users/Administrator/Desktop/jquery/test.html"//最终结果为["file://", "file:", "", undefined]//正常http请求如"http://www.baidu.com"//的到结果为["http://www.baidu.com", "http:", "www.baidu.com", undefined]//如果是"http://192.168.0.17:8080/baidu/com"//则得到的结果["http://192.168.0.17:8080", "http:", "192.168.0.17", "8080"]ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];//跨域请求是为了当我们有一个协议:host:port不匹配的时候if ( s.crossDomain == null ) {    parts = rurl.exec( s.url.toLowerCase() );    s.crossDomain = !!( parts &&        ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||            ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=            ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )        );}

  第四步,将传递数据data转化成一个查询字符串

//processData默认为true//默认情况下,通过data属性传递进来的数据,如果是一个对象(技术上讲,只要不是字符串),//都会处理转化成一个查询字符串,以配合默认内容类型 "application/x-www-form-urlencoded"if ( s.data && s.processData && typeof s.data !== "string" ) {    s.data = jQuery.param( s.data, s.traditional );}

  第五步,运行prefilters进行预处理

//运行prefiltersinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );

  预处理和分发器使用的是同一个函数inspectPrefiltersOrTransports,需要注意的是当dataType为jsonp的时候是以dataType为script的方式来处理的

  第六步,根据传递的选项设置默认参数处理(主要包括如果type是GET等类型,传递的数据将被附加到URL上;添加请求头如If-Modified-Since/If-None-Match、Content-Type、Accept等;)

//没有请求内容(type一般为GET的情况)if ( !s.hasContent ) {    //如果data可用,添加到url    if ( s.data ) {        cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data );        // #9682:删除data保证重试是不会被使用        delete s.data;    }    //cache默认值:true(dataType为'script'或'jsonp'时,则默认为false)。    //指示是否缓存URL请求。如果设为false将强制浏览器不缓存当前URL请求。    //该参数只对HEAD、GET请求有效(POST请求本身就不会缓存)    if ( s.cache === false ) {        //rts = /([?&])_=[^&]*/        s.url = rts.test( cacheURL ) ?            //如果已经有一个'_'参数,设置他的值            cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) :            //否则添加到url后面            //ajax_rquery = //?/            cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++;    }}// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.//ifModified默认为false//允许当前请求仅在服务器数据改变时获取新数据(如未更改,浏览器从缓存中获取数据)//它使用HTTP头信息Last-Modified来判断。从jQuery 1.4开始,他也会检查服务器指定的'etag'来确定数据是否已被修改。if ( s.ifModified ) {    if ( jQuery.lastModified[ cacheURL ] ) {        jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );    }    if ( jQuery.etag[ cacheURL ] ) {        jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );    }}//contentType默认值:'application/x-www-form-urlencoded; charset=UTF-8'。//使用指定的内容编码类型将数据发送给服务器。//W3C的xmlHttpRequest规范规定charset始终是UTF-8,将其改也无法强制浏览器更改字符编码。if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {    jqXHR.setRequestHeader( "Content-Type", s.contentType );}//设置Accept头,依赖于dataTypejqXHR.setRequestHeader(    "Accept",    s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?    s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :    s.accepts[ "*" ]);// Check for headers option//headers默认值:{}。//以对象形式指定附加的请求头信息。请求头X-Requested-With: xmlhttpRequest将始终被添加,//当然你也可以在此处修改默认的XMLHttpRequest值。//headers中的值可以覆盖beforeSend回调函数中设置的请求头(意即beforeSend先被调用)。for ( i in s.headers ) {    jqXHR.setRequestHeader( i, s.headers[ i ] );}…//安装回调到deferreds上for ( i in { success: 1, error: 1, complete: 1 } ) {    jqXHR[ i ]( s[ i ] );}
View Code
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表