{
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. Xfce4里添加登录后程序自动运行

    Xfce4里添加登录后程序自动运行 (注意该方法在登录桌面环境后才会自动运行程序. 在XUbuntu下测试过, Ubuntu下应该是类似的) 方法1: 找到这个东西, 自动添加一下 方法2: 在 .c ...

  2. Nginx-虚拟主机配置问题

    Nginx-虚拟主机配置问题 标签(空格分隔): linux,php,nginx,larave 这两天突然想配置lnmp环境,学习下Nginx配置结果就遇到了下边的问题 Nginx: server下的 ...

  3. 22.允许重复的容器(unordered_multiset)

    #include <string> #include <iostream> #include <unordered_set> using namespace std ...

  4. 线程1—Runnable

    随便选择两个城市作为预选旅游目标.实现两个独立的线程分别显示10次城市名,每次显示后休眠一段随机时间(1000ms以内),哪个先显示完毕,就决定去哪个城市.分别用Runnable接口和Thread类实 ...

  5. miniUI-SelectGrid 弹出选择表格-翻页选中

    介绍 mini中已经给出 弹出表格的里例子 :MiniUi版本 但是在应用过程中遇到写小问题就是没有办法翻页后一并连之前翻页选中的一起提交 以下是解决方案 正文 下面首先介绍  JS 代码 //存储已 ...

  6. Windows 相关

    Open the Windows Update troubleshooter If your computer is having problems finding and installing op ...

  7. 机器学习(七) PCA与梯度上升法 (下)

    五.高维数据映射为低维数据 换一个坐标轴.在新的坐标轴里面表示原来高维的数据. 低维 反向 映射为高维数据 PCA.py import numpy as np class PCA: def __ini ...

  8. 禁用cache

    Z:\src\services\network\network_context.cc:http_cache_enabled

  9. 记intel杯比赛中各种bug与debug【其四】:基于长短时记忆神经网络的中文分词的实现

    (标题长一点就能让外行人感觉到高大上) 直接切入主题好了,这个比赛还必须一个神经网络才可以 所以我们结合主题,打算写一个神经网络的中文分词 这里主要写一下数据的收集和处理,网络的设计,代码的编写和模型 ...

  10. HDU-1035 Robot Motion 模拟问题(水题)

    题目链接:https://cn.vjudge.net/problem/HDU-1035 水题 代码 #include <cstdio> #include <map> int h ...