{
var r20 = /%20/g, //全部空格
rbracket = /\[\]$/, //结尾位置匹配中括号
rCRLF = /\r?\n/g,
rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
rsubmittable = /^(?:input|select|textarea|keygen)/i; jQuery.fn.extend({
serialize: function() {
return jQuery.param( this.serializeArray() );
},
// console.log($('#form1').serializeArray());//[{'name':'a','value':'1'},{'name':'b','value':'2'}]
serializeArray: function() {
return this.map(function(){//map是数组都执行函数,返回结果集合
//只有表单有elements属性。
var elements = jQuery.prop( this, "elements" );
return elements ? jQuery.makeArray( elements ) : this;
})
.filter(function(){
var type = this.type;
// Use .is(":disabled") so that fieldset[disabled] works
return this.name && !jQuery( this ).is( ":disabled" ) &&
rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
( this.checked || !manipulation_rcheckableType.test( type ) );
})
.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();
}
}); //json对象、数组对象序列化成字符串
//$.param( [ {'name':1,'value':2} ] );//1=2,name为key,value为value
jQuery.param = function( a, traditional ) {
var prefix,
s = [],
//定义一个函数
add = function( key, value ) {
//是函数就让函数执行,得到返回值
value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
//编码
s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
}; // Set traditional to true for jQuery <= 1.3.2 behavior.
if ( traditional === undefined ) {
traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
} /*
var $a = $( [ {'name':1,'value':2},{'name':3,'value':4} ] )};
console.log( $.param($a) )
*/
if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
// Serialize the form elements
jQuery.each( a, function() {
add( this.name, this.value );//每一个a的name和value属性,
}); } else {
// a={'name':[1,3],'value':2},a={'name':{'a1':1,'a3':3},'value':2} add是回调进行拼接
for ( prefix in a ) {
buildParams( prefix, a[ prefix ], traditional, add );
}
} // 通过&链接,
return s.join( "&" ).replace( r20, "+" );
}; //buildParams(name,[1,3],traditional,add())
////buildParams(name,{'a1':1,'a3':3},traditional,add())
function buildParams( prefix, obj, traditional, add ) {
var name; if ( jQuery.isArray( obj ) ) {
jQuery.each( obj, function( i, v ) {
if ( traditional || rbracket.test( prefix ) ) {//传统方式
add( prefix, v ); } else {
// 多用三目运算符
buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
}
}); } else if ( !traditional && jQuery.type( obj ) === "object" ) {
// Serialize object item.
for ( name in obj ) {
buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
} } else {
// 不是数组不是对象,普通方式
add( prefix, obj );
}
} var
// Document location
ajaxLocParts,
ajaxLocation, ajax_nonce = jQuery.now(), ajax_rquery = /\?/,
rhash = /#.*$/,
rts = /([?&])_=[^&]*/,
rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
// #7653, #8125, #8152: local protocol detection
rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
rnoContent = /^(?:GET|HEAD)$/,
rprotocol = /^\/\//,
rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, // Keep a copy of the old load method
_load = jQuery.fn.load, /* Prefilters
* 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
* 2) These are called:
* - BEFORE asking for a transport
* - AFTER param serialization (s.data is a string if s.processData is true)
* 3) key is the dataType
* 4) the catchall symbol "*" can be used
* 5) execution will start with transport dataType and THEN continue down to "*" if needed
*/
//预过滤器,在发送ajax之前做一些处理
prefilters = {}, /* Transports bindings
* 1) key is the dataType
* 2) the catchall symbol "*" can be used
* 3) selection will start with transport dataType and THEN go to "*" if needed
*/
//分发器,
transports = {}, // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
allTypes = "*/".concat("*"); // #8138, IE may throw an exception when accessing
// a field from window.location if document.domain has been set
try {
ajaxLocation = location.href;
} catch( e ) {
// 兼容性,动态创建a标签,a标签的href是空,然后就可以获取当前页面地址
ajaxLocation = document.createElement( "a" );
ajaxLocation.href = "";
ajaxLocation = ajaxLocation.href;
} // Segment location into parts
ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
function addToPrefiltersOrTransports( structure ) { // dataTypeExpression is optional and defaults to "*"
return function( dataTypeExpression, func ) { if ( typeof dataTypeExpression !== "string" ) {
func = dataTypeExpression;
dataTypeExpression = "*";
} var dataType,
i = 0,
dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || []; if ( jQuery.isFunction( func ) ) {
// For each dataType in the dataTypeExpression
while ( (dataType = dataTypes[i++]) ) {
// Prepend if requested
if ( dataType[0] === "+" ) {
dataType = dataType.slice( 1 ) || "*";
(structure[ dataType ] = structure[ dataType ] || []).unshift( func ); // Otherwise append
} else {
(structure[ dataType ] = structure[ dataType ] || []).push( func );
}
}
}
};
} // Base inspection function for prefilters and transports
function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { var inspected = {},
seekingTransport = ( structure === transports ); function inspect( dataType ) {
var selected;
inspected[ dataType ] = true;
jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
if( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
options.dataTypes.unshift( dataTypeOrTransport );
inspect( dataTypeOrTransport );
return false;
} else if ( seekingTransport ) {
return !( selected = dataTypeOrTransport );
}
});
return selected;
} return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
} // 继承
function ajaxExtend( target, src ) {
var key, deep,
flatOptions = jQuery.ajaxSettings.flatOptions || {}; for ( key in src ) {
if ( src[ key ] !== undefined ) {
( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
}
}
if ( deep ) {
jQuery.extend( true, target, deep );
} return target;
} // $('#div1').load("1.html ol,{'name':'hello'}",function(a,b,c){})
jQuery.fn.load = function( url, params, callback ) {
if ( typeof url !== "string" && _load ) {
return _load.apply( this, arguments );
} var selector, type, response,
self = this,
off = url.indexOf(" "); if ( off >= 0 ) {
selector = url.slice( off );
url = url.slice( 0, off );
} // If it's a function
if ( jQuery.isFunction( params ) ) { // We assume that it's the callback
callback = params;
params = undefined; // Otherwise, build a param string
} else if ( params && typeof params === "object" ) {
type = "POST";//对象是post方式
} // If we have elements to modify, make the request
if ( self.length > 0 ) {
jQuery.ajax({
url: url,
type: type,//默认是get
dataType: "html",//返回数据类型
data: params //传输数据
}).done(function( responseText ) {//responseText返回的数据
response = arguments;
//self.html()添加到本元素的html内容中
self.html( selector ? //有过滤器 //动态创建div,添加返回的html,查找过滤器
jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) : // Otherwise use the full result
responseText );
//complete是完成不管成功失败
}).complete( callback && function( jqXHR, status ) {
self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
});
} return this;
}; // Attach a bunch of functions for handling common AJAX events
jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
jQuery.fn[ type ] = function( fn ){
return this.on( type, fn );
};
}); jQuery.extend({ // Counter for holding the number of active queries
active: 0, // Last-Modified header cache for next request
lastModified: {},
etag: {}, //ajax默认参数
ajaxSettings: {
url: ajaxLocation,//ajaxLocation = location.href;默认是当前页面地址
type: "GET",
isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), //是否本地
global: true, //是否能触发全局事件参数
processData: true,
async: true,
contentType: "application/x-www-form-urlencoded; charset=UTF-8",//数据编码操作, //注释是一样的,注释不写就是undefined,
/*
timeout: 0, //超时处理,超时就提示是否继续等待还是离开还是刷新
data: null,
dataType: null,
username: null, //服务器的验证
password: null,
cache: null, //cache:false,请求后面加一个时间戳,不会有缓存
throws: false, //
traditional: false, //传统模式
headers: {},
*/ accepts: {
"*": allTypes,
text: "text/plain",
html: "text/html",
xml: "application/xml, text/xml",
json: "application/json, text/javascript"
}, //检测响应头信息,判断返回的类型。
contents: {
xml: /xml/,
html: /html/,
json: /json/
}, responseFields: {
xml: "responseXML",
text: "responseText",
json: "responseJSON"
}, // 根据返回的响应头信息,做不同的转换。
converters: { // Convert anything to text
"* text": 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
}, // For options that shouldn't be deep extended:
// you can add your own custom options here if
// and when you create one that shouldn't be
// deep extended (see ajaxExtend)
flatOptions: {
url: true,
context: true
}
}, // 对json继承的封装
ajaxSetup: function( target, settings ) {
return settings ? //继承json过去
ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : // Extending ajaxSettings
ajaxExtend( jQuery.ajaxSettings, target );
}, ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
ajaxTransport: addToPrefiltersOrTransports( transports ), // Main method
/*
$.ajax({
url:url,
type:'post',
success : function(){},
error:function(){}
}); $.ajax('url',{
type:'post',
success : function(){},
error:function(){}
});
*/
ajax: function( url, options ) {//url是地址,options是json
if ( typeof url === "object" ) {//url是json就赋值给options
options = url;
url = undefined;
} // Force options to be an object
options = options || {}; var transport,
// URL without anti-cache param
cacheURL,
// Response headers
responseHeadersString,
responseHeaders,
// timeout handle
timeoutTimer,
// Cross-domain detection vars
parts,
// To know if global events are to be dispatched
fireGlobals,
// Loop variable
i,
//options覆盖默认参数,继承
s = jQuery.ajaxSetup( {}, options ),
// Callbacks context
callbackContext = s.context || s,
// Context for global events is callbackContext if it is a DOM node or jQuery collection
globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
jQuery( callbackContext ) :
jQuery.event,
// 延迟对象,回调对象
deferred = jQuery.Deferred(),
completeDeferred = jQuery.Callbacks("once memory"),
// Status-dependent callbacks
statusCode = s.statusCode || {},
// Headers (they are sent all at once)
requestHeaders = {},
requestHeadersNames = {},
// The jqXHR state
state = 0,
// Default abort message
strAbort = "canceled",
// Fake xhr
jqXHR = {
readyState: 0,//0--4,4的时候就是完成了 // 获取响应头
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 == null ? null : match;
}, // Raw string
getAllResponseHeaders: function() {
return state === 2 ? responseHeadersString : null;
}, // 设置请求头
setRequestHeader: function( name, value ) {
var lname = name.toLowerCase();
if ( !state ) {
name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
requestHeaders[ name ] = value;
}
return this;
}, // Overrides response content-type header
overrideMimeType: function( type ) {
if ( !state ) {
s.mimeType = type;
}
return this;
}, // Status-dependent callbacks
statusCode: function( map ) {
var code;
if ( map ) {
if ( state < 2 ) {
for ( code in map ) {
// Lazy-add the new callback in a way that preserves old ones
statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
}
} else {
// Execute the appropriate callbacks
jqXHR.always( map[ jqXHR.status ] );
}
}
return this;
}, // 错误的时候,例如超时,报错
abort: function( statusText ) {
var finalText = statusText || strAbort;
if ( transport ) {
transport.abort( finalText );
}
done( 0, finalText );
return this;
}
}; // 方法加进去
deferred.promise( jqXHR ).complete = completeDeferred.add;
jqXHR.success = jqXHR.done;
jqXHR.error = jqXHR.fail; // 对url处理,
s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" )
.replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); // Alias method option to type as per ticket #12004
s.type = options.method || options.type || s.method || s.type; // Extract dataTypes list
s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""]; // 跨域处理,不跟本网页是同一个主机地址。
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" ) ) )
);
} // Convert data if not already a string
if ( s.data && s.processData && typeof s.data !== "string" ) {
s.data = jQuery.param( s.data, s.traditional );
} // 触发回调
inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); // 请求完成了
if ( state === 2 ) {
return jqXHR;
} // We can fire global events as of now if asked to
fireGlobals = s.global; // Watch for a new set of requests
if ( fireGlobals && jQuery.active++ === 0 ) {
jQuery.event.trigger("ajaxStart");
} // Uppercase the type
s.type = s.type.toUpperCase(); // Determine if request has content
s.hasContent = !rnoContent.test( s.type ); // Save the URL in case we're toying with the If-Modified-Since
// and/or If-None-Match header later on
cacheURL = s.url; // More options handling for requests with no content
if ( !s.hasContent ) { // If data is available, append data to url
if ( s.data ) {
cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
// #9682: remove data so that it's not used in an eventual retry
delete s.data;
} // 不缓存就添加随机数
if ( s.cache === false ) {
s.url = rts.test( cacheURL ) ? // If there is already a '_' parameter, set its value
cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) : // Otherwise add one to the end
cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++;
}
} // 设置头信息,数据没有改变走缓存,通过后端配合,数据改变发起新的请求。
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 ] );
}
} // Set the correct header, if data is being sent
if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
jqXHR.setRequestHeader( "Content-Type", s.contentType );
} // 设置请求类型
jqXHR.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
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 and return
return jqXHR.abort();
} // aborting is no longer a cancellation
strAbort = "abort"; // 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 ( state < 2 ) {
done( -1, e );
// Simply rethrow otherwise
} else {
throw e;
}
}
} // Callback for when everything is done
function done( status, nativeStatusText, responses, headers ) {
var isSuccess, success, error, response, modified,
statusText = nativeStatusText; // 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 > 0 ? 4 : 0; // Determine if successful
isSuccess = status >= 200 && status < 300 || status === 304; // Get response data
if ( responses ) {
response = ajaxHandleResponses( s, jqXHR, responses );
} // Convert no matter what (that way responseXXX fields are always set)
response = ajaxConvert( s, response, jqXHR, isSuccess ); // If successful, handle type chaining
if ( isSuccess ) { // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
if ( s.ifModified ) {
modified = jqXHR.getResponseHeader("Last-Modified");
if ( modified ) {
jQuery.lastModified[ cacheURL ] = modified;
}
modified = jqXHR.getResponseHeader("etag");
if ( modified ) {
jQuery.etag[ cacheURL ] = modified;
}
} // if no content
if ( status === 204 || s.type === "HEAD" ) {
statusText = "nocontent"; // if not modified
} else if ( status === 304 ) {
statusText = "notmodified"; // If we have data, let's convert it
} else {
statusText = response.state;
success = response.data;
error = response.error;
isSuccess = !error;
}
} else {
// We extract error from statusText
// then normalize statusText and status for non-aborts
error = statusText;
if ( status || !statusText ) {
statusText = "error";
if ( status < 0 ) {
status = 0;
}
}
} // Set data for the fake xhr object
jqXHR.status = status;
jqXHR.statusText = ( nativeStatusText || 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( isSuccess ? "ajaxSuccess" : "ajaxError",
[ jqXHR, s, isSuccess ? success : error ] );
} // Complete
completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); if ( fireGlobals ) {
globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
// Handle the global AJAX counter
if ( !( --jQuery.active ) ) {
jQuery.event.trigger("ajaxStop");
}
}
}
//ajax方法结束后,返回jqXHR对象,$.ajax()方法后面就可以调用done、fail方法,$.ajax({url:url}).done().fail();
return jqXHR;
}, getJSON: function( url, data, callback ) {
return jQuery.get( url, data, callback, "json" );//调用jQuery.ajax()
}, getScript: function( url, callback ) {//请求js不传递参数
return jQuery.get( url, undefined, callback, "script" );
//调用jQuery.ajax()
}
}); //["get","post"]每一个元素调用function( i, method ),i是索引method是'get'、'post'
jQuery.each( [ "get", "post" ], function( i, method ) {
//get,post挂载到jQuery静态方法,通过中括号挂载。
//$.get('url',{'aa':123},function(){'成功回调'},'返回数据类型xml、json')
jQuery[ method ] = function( url, data, callback, type ) {
// shift arguments if data argument was omitted
if ( jQuery.isFunction( data ) ) {
type = type || callback;
callback = data;
data = undefined;
} return jQuery.ajax({
url: url,
type: method,
dataType: type,
data: data,
success: callback
});
};
}); /* Handles responses to an ajax request:
* - finds the right dataType (mediates between content-type and expected dataType)
* - returns the corresponding response
*/
function ajaxHandleResponses( s, jqXHR, responses ) { var ct, type, finalDataType, firstDataType,
contents = s.contents,
dataTypes = s.dataTypes; // Remove auto dataType and get content-type in the process
while( dataTypes[ 0 ] === "*" ) {
dataTypes.shift();
if ( ct === undefined ) {
ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
}
} // Check if we're dealing with a known content-type
if ( ct ) {
for ( type in contents ) {
if ( contents[ type ] && contents[ type ].test( ct ) ) {
dataTypes.unshift( type );
break;
}
}
} // Check to see if we have a response for the expected dataType
if ( dataTypes[ 0 ] in responses ) {
finalDataType = dataTypes[ 0 ];
} else {
// Try convertible dataTypes
for ( type in responses ) {
if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
finalDataType = type;
break;
}
if ( !firstDataType ) {
firstDataType = type;
}
}
// Or just use first one
finalDataType = finalDataType || firstDataType;
} // If we found a dataType
// We add the dataType to the list if needed
// and return the corresponding response
if ( finalDataType ) {
if ( finalDataType !== dataTypes[ 0 ] ) {
dataTypes.unshift( finalDataType );
}
return responses[ finalDataType ];
}
} //类型转换器,匹配返回的数据类型
function ajaxConvert( s, response, jqXHR, isSuccess ) {
var conv2, current, conv, tmp, prev,
converters = {},
// Work with a copy of dataTypes in case we need to modify it for conversion
dataTypes = s.dataTypes.slice(); // Create converters map with lowercased keys
if ( dataTypes[ 1 ] ) {
for ( conv in s.converters ) {
converters[ conv.toLowerCase() ] = s.converters[ conv ];
}
} current = dataTypes.shift(); // Convert to each sequential dataType
while ( current ) { if ( s.responseFields[ current ] ) {
jqXHR[ s.responseFields[ current ] ] = response;
} // Apply the dataFilter if provided
if ( !prev && isSuccess && s.dataFilter ) {
response = s.dataFilter( response, s.dataType );
} prev = current;
current = dataTypes.shift(); if ( current ) { // There's only work to do if current dataType is non-auto
if ( current === "*" ) { current = prev; // Convert response if prev dataType is non-auto and differs from current
} else if ( prev !== "*" && prev !== current ) { // Seek a direct converter
conv = converters[ prev + " " + current ] || converters[ "* " + current ]; // If none found, seek a pair
if ( !conv ) {
for ( conv2 in converters ) { // If conv2 outputs current
tmp = conv2.split( " " );
if ( tmp[ 1 ] === current ) { // If prev can be converted to accepted input
conv = converters[ prev + " " + tmp[ 0 ] ] ||
converters[ "* " + tmp[ 0 ] ];
if ( conv ) {
// Condense equivalence converters
if ( conv === true ) {
conv = converters[ conv2 ]; // Otherwise, insert the intermediate dataType
} else if ( converters[ conv2 ] !== true ) {
current = tmp[ 0 ];
dataTypes.unshift( tmp[ 1 ] );
}
break;
}
}
}
} // Apply converter (if not an equivalence)
if ( conv !== true ) { // Unless errors are allowed to bubble, catch and return them
if ( conv && s[ "throws" ] ) {
response = conv( response );
} else {
try {
response = conv( response );
} catch ( e ) {
return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
}
}
}
}
}
} return { state: "success", data: response };
}
// Install script dataType
jQuery.ajaxSetup({
accepts: {
script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
},
contents: {
script: /(?:java|ecma)script/
},
converters: {
"text script": function( text ) {
jQuery.globalEval( text );
return text;
}
}
}); // 发送ajax之前对数据做处理
jQuery.ajaxPrefilter( "script", function( s ) {
if ( s.cache === undefined ) {
s.cache = false;
}
if ( s.crossDomain ) {
s.type = "GET";
}
}); // Bind script tag hack transport
jQuery.ajaxTransport( "script", function( s ) {
// This transport only deals with cross domain requests
if ( s.crossDomain ) {
var script, callback;
return {
send: function( _, complete ) {
script = jQuery("<script>").prop({
async: true,
charset: s.scriptCharset,
src: s.url
}).on(
"load error",
callback = function( evt ) {
script.remove();
callback = null;
if ( evt ) {
complete( evt.type === "error" ? 404 : 200, evt.type );
}
}
);
document.head.appendChild( script[ 0 ] );
},
abort: function() {
if ( callback ) {
callback();
}
}
};
}
});
var oldCallbacks = [],
rjsonp = /(=)\?(?=&|$)|\?\?/; // Default jsonp settings
jQuery.ajaxSetup({
jsonp: "callback",
jsonpCallback: function() {
var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) );
this[ callback ] = true;
return callback;
}
}); // Detect, normalize options and install callbacks for jsonp requests
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { var callbackName, overwritten, responseContainer,
jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
"url" :
typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
); // Handle iff the expected data type is "jsonp" or we have a parameter to set
if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { // Get callback name, remembering preexisting value associated with it
callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
s.jsonpCallback() :
s.jsonpCallback; // Insert callback into url or form data
if ( jsonProp ) {
s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
} else if ( s.jsonp !== false ) {
s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
} // Use data converter to retrieve json after script execution
s.converters["script json"] = function() {
if ( !responseContainer ) {
jQuery.error( callbackName + " was not called" );
}
return responseContainer[ 0 ];
}; // force json dataType
s.dataTypes[ 0 ] = "json"; // Install callback
overwritten = window[ callbackName ];
window[ callbackName ] = function() {
responseContainer = arguments;
}; // Clean-up function (fires after converters)
jqXHR.always(function() {
// Restore preexisting value
window[ callbackName ] = overwritten; // Save back as free
if ( s[ callbackName ] ) {
// make sure that re-using the options doesn't screw things around
s.jsonpCallback = originalSettings.jsonpCallback; // save the callback name for future use
oldCallbacks.push( callbackName );
} // Call if it was a function and we have a response
if ( responseContainer && jQuery.isFunction( overwritten ) ) {
overwritten( responseContainer[ 0 ] );
} responseContainer = overwritten = undefined;
}); // Delegate to script
return "script";
}
});
jQuery.ajaxSettings.xhr = function() {
try {
return new XMLHttpRequest();
} catch( e ) {}
}; var xhrSupported = jQuery.ajaxSettings.xhr(),
xhrSuccessStatus = {
// file protocol always yields status code 0, assume 200
0: 200,
// Support: IE9
// #1450: sometimes IE returns 1223 when it should be 204
1223: 204
},
// Support: IE9
// We need to keep track of outbound xhr and abort them manually
// because IE is not smart enough to do it all by itself
xhrId = 0,
xhrCallbacks = {}; if ( window.ActiveXObject ) {
jQuery( window ).on( "unload", function() {
for( var key in xhrCallbacks ) {
xhrCallbacks[ key ]();
}
xhrCallbacks = undefined;
});
} jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
jQuery.support.ajax = xhrSupported = !!xhrSupported; jQuery.ajaxTransport(function( options ) {
var callback;
// Cross domain only allowed if supported through XMLHttpRequest
if ( jQuery.support.cors || xhrSupported && !options.crossDomain ) {
return {
send: function( headers, complete ) {
var i, id,
//xhr是原生XMLHttpRequest对象
xhr = options.xhr();
xhr.open( options.type, options.url, options.async, options.username, options.password );
// Apply custom fields if provided
if ( options.xhrFields ) {
for ( i in options.xhrFields ) {
xhr[ i ] = options.xhrFields[ i ];
}
}
// 跨域处理
if ( options.mimeType && xhr.overrideMimeType ) {
xhr.overrideMimeType( options.mimeType );
}
// X-Requested-With header
// For cross-domain requests, seeing as conditions for a preflight are
// akin to a jigsaw puzzle, we simply never set it to be sure.
// (it can always be set on a per-request basis or even using ajaxSetup)
// For same-domain requests, won't change header if already provided.
if ( !options.crossDomain && !headers["X-Requested-With"] ) {
headers["X-Requested-With"] = "XMLHttpRequest";
}
// Set headers
for ( i in headers ) {
xhr.setRequestHeader( i, headers[ i ] );
}
// Callback
callback = function( type ) {
return function() {
if ( callback ) {
delete xhrCallbacks[ id ];
callback = xhr.onload = xhr.onerror = null;
if ( type === "abort" ) {
xhr.abort();
} else if ( type === "error" ) {
complete(
// file protocol always yields status 0, assume 404
xhr.status || 404,
xhr.statusText
);
} else {
complete(
xhrSuccessStatus[ xhr.status ] || xhr.status,
xhr.statusText,
// Support: IE9
// #11426: When requesting binary data, IE9 will throw an exception
// on any attempt to access responseText
typeof xhr.responseText === "string" ? {
text: xhr.responseText
} : undefined,
xhr.getAllResponseHeaders()
);
}
}
};
};
// 真正完成才会走onload
xhr.onload = callback();
xhr.onerror = callback("error");
// Create the abort callback
callback = xhrCallbacks[( id = xhrId++ )] = callback("abort");
// Do send the request
// This may raise an exception which is actually
// handled in jQuery.ajax (so no try/catch here)
//发送
xhr.send( options.hasContent && options.data || null );
},
abort: function() {
if ( callback ) {
callback();
}
}
};
}
}); }

jquery源码10-提交的数据和ajax()的更多相关文章

  1. jQuery 源码分析(十五) 数据操作模块 val详解

    jQuery的属性操作模块总共有4个部分,本篇说一下最后一个部分:val值的操作,也是属性操作里最简单的吧,只有一个API,如下: val(vlaue)        ;获取匹配元素集合中第一个元素的 ...

  2. jQuery 源码分析(十四) 数据操作模块 类样式操作 详解

    jQuery的属性操作模块总共有4个部分,本篇说一下第3个部分:类样式操作部分,用于修改DOM元素的class特性的,对于类样式操作来说,jQuery并没有定义静态方法,而只定义了实例方法,如下: a ...

  3. jQuery 源码分析(十二) 数据操作模块 html特性 详解

    jQuery的属性操作模块总共有4个部分,本篇说一下第1个部分:HTML特性部分,html特性部分是对原生方法getAttribute()和setAttribute()的封装,用于修改DOM元素的特性 ...

  4. jQuery源码分析系列

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...

  5. [转]jQuery源码分析系列

    文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...

  6. jQuery源码分析系列(转载来源Aaron.)

    声明:非本文原创文章,转载来源原文链接Aaron. 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAa ...

  7. jQuery源码分析系列——来自Aaron

    jQuery源码分析系列——来自Aaron 转载地址:http://www.cnblogs.com/aaronjs/p/3279314.html 版本截止到2013.8.24 jQuery官方发布最新 ...

  8. 【菜鸟学习jquery源码】数据缓存与data()

    前言 最近比较烦,深圳的工作还没着落,论文不想弄,烦.....今天看了下jquery的数据缓存的代码,参考着Aaron的源码分析,自己有点理解了,和大家分享下.以后也打算把自己的jquery的学习心得 ...

  9. jQuery源码逐行分析学习01(jQuery的框架结构简化)

    最近在学习jQuery源码,在此,特别做一个分享,把所涉及的内容都记录下来,其中有不妥之处还望大家指出,我会及时改正.望各位大神不吝赐教!同时,这也是我的第一篇前端技术博客,对博客编写还不是很熟悉,美 ...

随机推荐

  1. 图论之堆优化的Prim

    本题模板,最小生成树,洛谷P3366 题目描述 如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz 输入输出格式 输入格式: 第一行包含两个整数N.M,表示该图共有N个结点和M条无向边 ...

  2. Flume 启动

    Configuration是Flume项目的入口程序了,当我们输入 bin/flume-ng agent --conf conf --conf-file conf/kafka1.properties ...

  3. 点击鼠标右键弹出错误提示:CrashHandler initialization error

    电脑重装系统后,什么都没有了,重装部分必须用的软件后,不管是在桌面还是在文件夹中,当点击鼠标右键时,总是弹出错误,如下图所示: 上网找解决方法,也没有找到,但是看错误,是与SVN有关. 产生原因:To ...

  4. Decorator - 利用装饰器武装前端代码

    历史 以前做后端时,接触过一点Spring,也是第一次了解DI.IOC等概念,面向切面编程,对于面向对象编程还不怎么熟练的情况下,整个人慌的一批,它的日志记录.数据库配置等都非常方便,不回侵入到业务代 ...

  5. 关于git及其github的使用

    一:序言(就是瞎扯) 人们都说不会使用git和github的程序员都不是好程序员,是的,当我第一次听到的时候有点失望.因为我也不会...但是这句话激起了我学习使用git的动力(其实也没怎么深入的学习) ...

  6. unity C# 获取有关文件、文件夹和驱动器的信息

    class FileSysInfo { static void Main() { // You can also use System.Environment.GetLogicalDrives to ...

  7. 【转】 HTML解析:基于XPath的C#类库HtmlAgiliytyPack

    [转] HTML解析:基于XPath的C#类库HtmlAgiliytyPack 最近处于毕业设计开始阶段,前期工作需要去国外的一些专业数据库网站比对一些所需TF家族信息,为了快捷方便,想到用程序去帮助 ...

  8. new期间的异常

    new包含两步,调用operator new申请空间,以及调用构造函数. 如果第一步结束之后,第二步发生异常,需要归还第一步的空间. 编译器帮我们做了这件事情,并且会调用对应的delete. 另外 n ...

  9. Dig A Well For Yourself

    See Paul's essay:  , I found paul is a genius, double checking. Mars June 2015

  10. 关于Android手机MTP模式连接的一些设置(win7和ubuntu下,以红米1s为例)

    有些手机的MTP模式在电脑上识别不了,须要一些设置才干够,以下就网上收集来的一些设置方法集中贴过来: 一. win7下 參考:http://blog.ammrli.com/?p=1117 1.在设备管 ...