zoukankan      html  css  js  c++  java
  • Jquery中.ajax和.post详解

    之前写过一篇《.NET MVC 异步提交和返回参数》 ,里面有一些ajax的内容,但是不深入,这次详细剖析下jquery中$.ajax的用法。

    首先,上代码;

    jquery-1.5.1 $.ajax源码:

    jQuery.extend({
    
        getScript: function( url, callback ) {
            return jQuery.get( url, undefined, callback, "script" );
        },
    
        getJSON: function( url, data, callback ) {
            return jQuery.get( url, data, callback, "json" );
        },
    
        // Creates a full fledged settings object into target
        // with both ajaxSettings and settings fields.
        // If target is omitted, writes into ajaxSettings.
        ajaxSetup: function ( target, settings ) {
            if ( !settings ) {
                // Only one parameter, we extend ajaxSettings
                settings = target;
                target = jQuery.extend( true, jQuery.ajaxSettings, settings );
            } else {
                // target was provided, we extend into it
                jQuery.extend( true, target, jQuery.ajaxSettings, settings );
            }
            // Flatten fields we don't want deep extended
            for( var field in { context: 1, url: 1 } ) {
                if ( field in settings ) {
                    target[ field ] = settings[ field ];
                } else if( field in jQuery.ajaxSettings ) {
                    target[ field ] = jQuery.ajaxSettings[ field ];
                }
            }
            return target;
        },
    
        ajaxSettings: {
            url: ajaxLocation,
            isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
            global: true,
            type: "GET",
            contentType: "application/x-www-form-urlencoded",
            processData: true,
            async: true,
            /*
            timeout: 0,
            data: null,
            dataType: null,
            username: null,
            password: null,
            cache: null,
            traditional: false,
            headers: {},
            crossDomain: null,
            */
    
            accepts: {
                xml: "application/xml, text/xml",
                html: "text/html",
                text: "text/plain",
                json: "application/json, text/javascript",
                "*": "*/*"
            },
    
            contents: {
                xml: /xml/,
                html: /html/,
                json: /json/
            },
    
            responseFields: {
                xml: "responseXML",
                text: "responseText"
            },
    
            // List of data converters
            // 1) key format is "source_type destination_type" (a single space in-between)
            // 2) the catchall symbol "*" can be used for source_type
            converters: {
    
                // Convert anything to text
                "* text": window.String,
    
                // Text to html (true = no transformation)
                "text html": true,
    
                // Evaluate text as a json expression
                "text json": jQuery.parseJSON,
    
                // Parse text as xml
                "text xml": jQuery.parseXML
            }
        },
    
        ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
        ajaxTransport: addToPrefiltersOrTransports( transports ),
    
        // Main method
        ajax: function( url, options ) {
    
            // If url is an object, simulate pre-1.5 signature
            if ( typeof url === "object" ) {
                options = url;
                url = undefined;
            }
    
            // Force options to be an object
            options = options || {};
    
            var // Create the final options object
                s = jQuery.ajaxSetup( {}, options ),
                // Callbacks context
                callbackContext = s.context || s,
                // Context for global events
                // It's the callbackContext if one was provided in the options
                // and if it's a DOM node or a jQuery collection
                globalEventContext = callbackContext !== s &&
                    ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
                            jQuery( callbackContext ) : jQuery.event,
                // Deferreds
                deferred = jQuery.Deferred(),
                completeDeferred = jQuery._Deferred(),
                // Status-dependent callbacks
                statusCode = s.statusCode || {},
                // ifModified key
                ifModifiedKey,
                // Headers (they are sent all at once)
                requestHeaders = {},
                // Response headers
                responseHeadersString,
                responseHeaders,
                // transport
                transport,
                // timeout handle
                timeoutTimer,
                // Cross-domain detection vars
                parts,
                // The jqXHR state
                state = 0,
                // To know if global events are to be dispatched
                fireGlobals,
                // Loop variable
                i,
                // Fake xhr
                jqXHR = {
    
                    readyState: 0,
    
                    // Caches the header
                    setRequestHeader: function( name, value ) {
                        if ( !state ) {
                            requestHeaders[ name.toLowerCase().replace( rucHeaders, rucHeadersFunc ) ] = value;
                        }
                        return this;
                    },
    
                    // Raw string
                    getAllResponseHeaders: function() {
                        return state === 2 ? responseHeadersString : null;
                    },
    
                    // Builds headers hashtable if needed
                    getResponseHeader: function( key ) {
                        var match;
                        if ( state === 2 ) {
                            if ( !responseHeaders ) {
                                responseHeaders = {};
                                while( ( match = rheaders.exec( responseHeadersString ) ) ) {
                                    responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
                                }
                            }
                            match = responseHeaders[ key.toLowerCase() ];
                        }
                        return match === undefined ? null : match;
                    },
    
                    // Overrides response content-type header
                    overrideMimeType: function( type ) {
                        if ( !state ) {
                            s.mimeType = type;
                        }
                        return this;
                    },
    
                    // Cancel the request
                    abort: function( statusText ) {
                        statusText = statusText || "abort";
                        if ( transport ) {
                            transport.abort( statusText );
                        }
                        done( 0, statusText );
                        return this;
                    }
                };
    
            // Callback for when everything is done
            // It is defined here because jslint complains if it is declared
            // at the end of the function (which would be more logical and readable)
            function done( status, statusText, responses, headers ) {
    
                // Called once
                if ( state === 2 ) {
                    return;
                }
    
                // State is "done" now
                state = 2;
    
                // Clear timeout if it exists
                if ( timeoutTimer ) {
                    clearTimeout( timeoutTimer );
                }
    
                // Dereference transport for early garbage collection
                // (no matter how long the jqXHR object will be used)
                transport = undefined;
    
                // Cache response headers
                responseHeadersString = headers || "";
    
                // Set readyState
                jqXHR.readyState = status ? 4 : 0;
    
                var isSuccess,
                    success,
                    error,
                    response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
                    lastModified,
                    etag;
    
                // If successful, handle type chaining
                if ( status >= 200 && status < 300 || status === 304 ) {
    
                    // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
                    if ( s.ifModified ) {
    
                        if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
                            jQuery.lastModified[ ifModifiedKey ] = lastModified;
                        }
                        if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
                            jQuery.etag[ ifModifiedKey ] = etag;
                        }
                    }
    
                    // If not modified
                    if ( status === 304 ) {
    
                        statusText = "notmodified";
                        isSuccess = true;
    
                    // If we have data
                    } else {
    
                        try {
                            success = ajaxConvert( s, response );
                            statusText = "success";
                            isSuccess = true;
                        } catch(e) {
                            // We have a parsererror
                            statusText = "parsererror";
                            error = e;
                        }
                    }
                } else {
                    // We extract error from statusText
                    // then normalize statusText and status for non-aborts
                    error = statusText;
                    if( !statusText || status ) {
                        statusText = "error";
                        if ( status < 0 ) {
                            status = 0;
                        }
                    }
                }
    
                // Set data for the fake xhr object
                jqXHR.status = status;
                jqXHR.statusText = statusText;
    
                // Success/Error
                if ( isSuccess ) {
                    deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
                } else {
                    deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
                }
    
                // Status-dependent callbacks
                jqXHR.statusCode( statusCode );
                statusCode = undefined;
    
                if ( fireGlobals ) {
                    globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
                            [ jqXHR, s, isSuccess ? success : error ] );
                }
    
                // Complete
                completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
    
                if ( fireGlobals ) {
                    globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] );
                    // Handle the global AJAX counter
                    if ( !( --jQuery.active ) ) {
                        jQuery.event.trigger( "ajaxStop" );
                    }
                }
            }
    
            // Attach deferreds
            deferred.promise( jqXHR );
            jqXHR.success = jqXHR.done;
            jqXHR.error = jqXHR.fail;
            jqXHR.complete = completeDeferred.done;
    
            // Status-dependent callbacks
            jqXHR.statusCode = function( map ) {
                if ( map ) {
                    var tmp;
                    if ( state < 2 ) {
                        for( tmp in map ) {
                            statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
                        }
                    } else {
                        tmp = map[ jqXHR.status ];
                        jqXHR.then( tmp, tmp );
                    }
                }
                return this;
            };
    
            // Remove hash character (#7531: and string promotion)
            // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
            // We also use the url parameter if available
            s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
    
            // Extract dataTypes list
            s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
    
            // Determine if a cross-domain request is in order
            if ( !s.crossDomain ) {
                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 ) ) )
                );
            }
    
            // Convert data if not already a string
            if ( s.data && s.processData && typeof s.data !== "string" ) {
                s.data = jQuery.param( s.data, s.traditional );
            }
    
            // Apply prefilters
            inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
    
            // If request was aborted inside a prefiler, stop there
            if ( state === 2 ) {
                return false;
            }
    
            // We can fire global events as of now if asked to
            fireGlobals = s.global;
    
            // Uppercase the type
            s.type = s.type.toUpperCase();
    
            // Determine if request has content
            s.hasContent = !rnoContent.test( s.type );
    
            // Watch for a new set of requests
            if ( fireGlobals && jQuery.active++ === 0 ) {
                jQuery.event.trigger( "ajaxStart" );
            }
    
            // More options handling for requests with no content
            if ( !s.hasContent ) {
    
                // If data is available, append data to url
                if ( s.data ) {
                    s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
                }
    
                // Get ifModifiedKey before adding the anti-cache parameter
                ifModifiedKey = s.url;
    
                // Add anti-cache in url if needed
                if ( s.cache === false ) {
    
                    var ts = jQuery.now(),
                        // try replacing _= if it is there
                        ret = s.url.replace( rts, "$1_=" + ts );
    
                    // if nothing was replaced, add timestamp to the end
                    s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
                }
            }
    
            // Set the correct header, if data is being sent
            if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
                requestHeaders[ "Content-Type" ] = s.contentType;
            }
    
            // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
            if ( s.ifModified ) {
                ifModifiedKey = ifModifiedKey || s.url;
                if ( jQuery.lastModified[ ifModifiedKey ] ) {
                    requestHeaders[ "If-Modified-Since" ] = jQuery.lastModified[ ifModifiedKey ];
                }
                if ( jQuery.etag[ ifModifiedKey ] ) {
                    requestHeaders[ "If-None-Match" ] = jQuery.etag[ ifModifiedKey ];
                }
            }
    
            // Set the Accepts header for the server, depending on the dataType
            requestHeaders.Accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
                s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
                s.accepts[ "*" ];
    
            // Check for headers option
            for ( i in s.headers ) {
                jqXHR.setRequestHeader( i, s.headers[ i ] );
            }
    
            // Allow custom headers/mimetypes and early abort
            if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
                    // Abort if not done already
                    jqXHR.abort();
                    return false;
    
            }
    
            // Install callbacks on deferreds
            for ( i in { success: 1, error: 1, complete: 1 } ) {
                jqXHR[ i ]( s[ i ] );
            }
    
            // Get transport
            transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
    
            // If no transport, we auto-abort
            if ( !transport ) {
                done( -1, "No Transport" );
            } else {
                jqXHR.readyState = 1;
                // Send global event
                if ( fireGlobals ) {
                    globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
                }
                // Timeout
                if ( s.async && s.timeout > 0 ) {
                    timeoutTimer = setTimeout( function(){
                        jqXHR.abort( "timeout" );
                    }, s.timeout );
                }
    
                try {
                    state = 1;
                    transport.send( requestHeaders, done );
                } catch (e) {
                    // Propagate exception as error if not done
                    if ( status < 2 ) {
                        done( -1, e );
                    // Simply rethrow otherwise
                    } else {
                        jQuery.error( e );
                    }
                }
            }
    
            return jqXHR;
        },
    
        // Serialize an array of form elements or a set of
        // key/values into a query string
        param: function( a, traditional ) {
            var s = [],
                add = function( key, value ) {
                    // If value is a function, invoke it and return its value
                    value = jQuery.isFunction( value ) ? value() : value;
                    s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
                };
    
            // Set traditional to true for jQuery <= 1.3.2 behavior.
            if ( traditional === undefined ) {
                traditional = jQuery.ajaxSettings.traditional;
            }
    
            // If an array was passed in, assume that it is an array of form elements.
            if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
                // Serialize the form elements
                jQuery.each( a, function() {
                    add( this.name, this.value );
                } );
    
            } else {
                // If traditional, encode the "old" way (the way 1.3.2 or older
                // did it), otherwise encode params recursively.
                for ( var prefix in a ) {
                    buildParams( prefix, a[ prefix ], traditional, add );
                }
            }
    
            // Return the resulting serialization
            return s.join( "&" ).replace( r20, "+" );
        }
    });
    View Code

    Jquery的$.ajax的用法:

    jQuery.ajax( options ) : 通过 HTTP 请求加载远程数据,这个是jQuery 的底层 AJAX 实现。简单易用的高层实现见 $.get, $.post 等。

      $.ajax() 返回其创建的 XMLHttpRequest 对象。大多数情况下你无需直接操作该对象,但特殊情况下可用于手动终止请求。

      注意: 如果你指定了 dataType 选项,请确保服务器返回正确的MIME信息,(如xml返回"text/xml")。错误的MIME类型可能导致不可预知的错误。见Specifying the Data Type for AJAX Requests 。

    当设置 datatype 类型为 'script' 的时候,所有的远程(不在同一个域中)POST请求都回转换为GET方式。

      $.ajax() 只有一个参数:参数 key/value 对象,包含各配置及回调函数信息。详细参数选项见下。

      jQuery 1.2 中,您可以跨域加载 JSON 数据,使用时需将数据类型设置为 JSONP。使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。数据类型设置为 "jsonp" 时,jQuery 将自动调用回调函数。(这个我不是很懂)

    jquery ajax 参数列表:

    url(String)

    (默认: 当前页地址) 发送请求的地址。

    type(String)

    请求方式 (参数有两种 "POST" 和 "GET"),默认为 "GET"。注意:其它 HTTP 请求方法,如 PUT 和 DELETE 也可以使用,但仅部分浏览器支持。

    timeout(Number)

    设置请求超时时间(毫秒)。此设置将覆盖全局设置。

    async(Boolean)

    (默认: true) 设置为true的情况下所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false。注意,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行。

    beforeSend(Function)

    发送请求前可修改 XMLHttpRequest 对象的函数,如添加自定义 HTTP 头。XMLHttpRequest 对象是唯一的参数。

    function(XMLHttpRequest){
    
     this; // the options for this ajax request
    
    }

    cache(Boolean)

    是否将请求结果设置缓存(默认: true) ,设置为 false 将不会从浏览器缓存中加载请求信息,注意开发初期最好设置为false,否则不方便调试的哦。

    complete(Function)

    请求完成后回调函数 (请求成功或失败时均调用)。参数: XMLHttpRequest 对象,成功信息字符串。

    function(XMLHttpRequest,textStatus){
    
     this;//theoptionsforthisajaxrequest
    
    }

    contentType(String)

    (默认: "application/x-www-form-urlencoded") 发送信息至服务器时内容编码类型。默认值适合大多数应用场合。

    data(Object,String)

    发送到服务器的数据。将自动转换为请求字符串格式。GET 请求中将附加在 URL 后。查看 processData 选项说明以禁止此自动转换。必须为 Key/Value格式。如果为数组,jQuery 将自动为不同值对应同一个名称。如 {foo:["bar1", "bar2"]} 转换为 '&foo=bar1&foo=bar2'。

    dataType(String)

    定义服务器返回的数据类型。如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息返回 responseXML 或 responseText,并作为回调函数参数传递,可用值:

    "xml": 返回 XML 格式数据,可用 jQuery 处理。

    "html": 返回纯文本 HTML 格式数据;可包含 script 元素。

    "script": 返回纯文本 JavaScript 代码。不会自动缓存结果。

    "json": 返回 JSON 数据 。

    "jsonp": JSONP 格式。使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。

    error(Function)

    (默认: 自动判断 (xml 或 html)) 请求失败时将调用此方法。这个方法有三个参数:XMLHttpRequest 对象,错误信息,(可能)捕获的错误对象。

    function(XMLHttpRequest,textStatus,errorThrown){
    
     //通常情况下textStatus和errorThown只有其中一个有值
    
     this;//theoptionsforthisajaxrequest
    
    }

    global(Boolean)

    是否触发全局 AJAX 事件(默认: true) 。设置为 false 将不会触发全局 AJAX 事件,如 ajaxStart 或 ajaxStop 。可用于控制不同的Ajax事件

    ifModified(Boolean)

    (默认: false) 仅在服务器数据改变时获取新数据。使用 HTTP 包 Last-Modified 头信息判断。

    processData(Boolean)

    设置发送数据的信息格式(默认: true),设置为 true 的时候发送的数据将被转换为对象(技术上讲并非字符串) 以配合默认内容类型 "application/x-www-form-urlencoded"。如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。

    success(Function)

    请求成功后回调函数。这个方法有两个参数:服务器返回数据,返回状态

    function(data,textStatus){
    
     //datacouldbexmlDoc,jsonObj,html,text,etc...
    
     this;//theoptionsforthisajaxrequest
    
    }

    下面以一则示例解释一下该方法的具体的用法:

    $.ajax({
    
      type:'get',
    
      url:'http://www.www.daimajiayuan.com/rss',
    
      beforeSend:function(XMLHttpRequest){
    
        //ShowLoading();
    
      },
    
      success:function(data,textStatus){
    
        $('.ajax.ajaxResult').html('');
    
        $('item',data).each(function(i,domEle){
    
          $('.ajax.ajaxResult').append('<li>'+$(domEle).children('title').text()+'</li>');
    
        });
    
      },
    
      complete:function(XMLHttpRequest,textStatus){
    
        //HideLoading();
    
      },
    
      error:function(){
    
        //请求出错处理
    
      }
    
    });

    Jquery的$.post的用法:

    jQuery.post( url, [data], [callback], [type] ) :使用POST方式来进行异步请求

    jquery $.post 方法参数列表(说明):

    url (String) : 发送请求的URL地址.

    data (Map) : (可选) 要发送给服务器的数据,以 Key/value 的键值对形式表示,可将此值放到url中。

    callback (Function) : (可选) 载入成功时回调函数(只有当Response的返回状态是success才能调用该方法)。

    type (String) : (可选)客户端请求的数据类型(JSON,XML,等等)

    这是一个简单的 POST 请求功能以取代复杂 $.ajax ,请求成功时可调用回调函数。如果需要在出错时执行函数,请使用 $.ajax。

    下面是一个使用$.post的简单示例代码:

    $.post(
    
      'http://www.daimajiayuan.com/ajax.php',
    
      {Action:"post",Name:"lulu"},
    
      function(data,textStatus){
    
        //data可以是xmlDoc,jsonObj,html,text,等等.
    
        //this;//这个Ajax请求的选项配置信息,请参考jQuery.get()说到的this
    
        alert(data.result);
    
      },
    
      "json"//这里设置了请求的返回格式为"json"
    
    );

    如果你设置了请求的格式为"json",此时你没有设置Response回来的ContentType 为:Response.ContentType = "application/json"; 那么你将无法捕捉到返回的数据。

    注意,上面的示例中 alert(data.result); 由于设置了Accept报头为"json",这里返回的data就是一个对象,因此不需要用eval()来转换为对象。

  • 相关阅读:
    [Flux] Component / Views
    [Flux] Stores
    [WebStrom] Change default cmd to Cygwin
    [AngularJS] ng-if vs ng-show
    [ES6] Array.find()
    [ES6] Array.findIndex()
    [Javascript] Object.assign()
    [Javascript] Intro to the Web Audio API
    [Falcor] Indroduce to Model
    [Farcol] Introduce
  • 原文地址:https://www.cnblogs.com/qixinbo/p/7428013.html
Copyright © 2011-2022 走看看