jQuery源码分析之$.get/$.post/serialize/serializeArray方法详解

get/post源码如下:

jQuery.each( [ "get", "post" ], function( i, method ) {
	//如果第二个参数就是函数,那么表示没有传入数据!
	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;
		}
        //调用get那么type就是get。调用post那么type就是post!
		return jQuery.ajax({
			url: url,
			type: method,
			dataType: type,
			data: data,
			success: callback
		});
	};
});
note:

(1)get/post方法底层调用的都是ajax方法。传入的第四个参数用于指定dataType,也就是从服务器端获取的数据类型!

(2)Get方法不适合传送数据量较大的数据,同时其请求的历史信息也会保存在浏览器的缓存中,有一定的风险,而post不存在这两种情况!
 那么get请求为什么会在ajax请求中缓存:(看ajax方法中的代码片段)

           var rnoContent = /^(?:GET|HEAD)$/
           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;
                //如果是get/head请求,执行这里的if语句,但是我们的get/post请求中无法指定cache,所以s.cache===false为假!因此就会缓存!
               //也就是说我们的URL后面不会添加当前时间,所以会缓存,这是GET请求的特点!但是post请求不管怎么样都不会缓存!
		// More options handling for requests with no content
		if ( !s.hasContent ) {//post请求这里不会执行,所以不会缓存!
			// If data is available, append data to url
			if ( s.data ) {
				cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
				// #9682: remove data so that it's not used in an eventual retry
				delete s.data;
			}
			// Add anti-cache in url if needed在$.post/$.get中无法指定cache
			if ( s.cache === false ) {
				s.url = rts.test( cacheURL ) ?
					// If there is already a '_' parameter, set its value
					cacheURL.replace( rts, "$1_=" + nonce++ ) :
					// Otherwise add one to the end
					cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
			}
		}

typeString类型

默认值:"GET"。请求类型,可以为'POST'或'GET'。注意:你也可以在此处使用诸如'PUT'、'DELETE'等其他请求类型,但它们不被所有浏览器支持。

这是codeplayer上面的说明。那么ajax方法是怎么做到默认是"GET",请看下面的片段:

	ajaxSettings: {
		url: ajaxLocation,
		type: "GET",
		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
		global: true,
		processData: true,
		async: true,
		contentType: "application/x-www-form-urlencoded; charset=UTF-8"}
note:这说明,默认的type是"GET",而且默认会执行全局事件;同时processData也是true;同时aync为true,表示默认是异步的!

processDataBoolean类型

默认值:true默认情况下,通过data属性传递进来的数据,如果是一个对象(技术上讲,只要不是字符串),都会处理转化成一个查询字符串,以配合默认内容类型 "application/x-www-form-urlencoded"。如果要发送 DOM树信息或其它不希望转换的信息,请设置为false

下面我们来看看基于get/post方法的getJSON,getScript方法:

getJSON源码:

getJSON: function( url, data, callback ) {
		return jQuery.get( url, data, callback, "json" );
	}
这也就是告诉ajax函数,dataType是"json",也就是必须把服务器端返回的数据通过parseJSON进行处理。

getScript源码:

getScript: function( url, callback ) {
		return jQuery.get( url, undefined, callback, "script" );
	}
这说明getScript调用的时候是只能传送URL和回调函数。所以data默认就是null了,同时"script"告诉ajax方法我的dataType是"script",所以在ajax方法中会经过ajaxPrefilters,ajaxTransport,ajaxConverter等多重处理,最后通过jQuery.globalEval来执行回调函数!

其实还可以通过$("<script><\/script>").appendTo("head")来加载脚本,可以通过阅读parseHTML源码来了解其中的原理!

在ajax请求或者get/post请求的时候我们需要把表单序列化,于是引入了serialize方法:

代码1:

var obj={
	name:"xxx",
	sex:"female"
}
var result1=encodeURIComponent(obj);
var result2=decodeURIComponent(result1);
alert(result1+"->"+result2);//通过encodeURIComponent把对象变成一个字符串进行传递给服务器,通过decodeURIComponent把这个对象解码!
serializeArray和serialize源码分析:

var rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
var       rsubmittable = /^(?:input|select|textarea|keygen)/i;
 var rcheckableType = (/^(?:checkbox|radio)$/i);
var   rCRLF = /\r?\n/g
jQuery.fn.extend({
	serialize: function() {
		return jQuery.param( this.serializeArray() );
	},
	serializeArray: function() {
		//如果有elements那么获取该元素的elements,否则还是自身!
		return this.map(function() {
			// Can add propHook for "elements" to filter or add form elements
			var elements = jQuery.prop( this, "elements" );
			return elements ? jQuery.makeArray( elements ) : this;
		})
		.filter(function() {
			var type = this.type;
			//filter方法里面已经是DOM元素了
			// Use .is(":disabled") so that fieldset[disabled] works
			//必须有name属性,同时该元素不是隐藏的元素,同时nodeName必须是input/select/textarea/kengen元素
			//同时该元素的type类型必须不是sumbit/button/image/reset/file类型,而且该元素的checked属性必须存在
			//如果checkded不存在,那么该元素类型必须不是checkbox/radio类型
			return this.name && !jQuery( this ).is( ":disabled" ) &&
				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
				( this.checked || !rcheckableType.test( type ) );
		})
		.map(function( i, elem ) {
			//这里面真正对元素进行处理
			//获取该元素的值,如果值是null那么返回的值就是null
			//如果该元素的值存在,同时如果该值是一个数组,那么对
			//该元素的值进行迭代,放入一个对象当中,name是元素的名称,键值是元素的值,不过该值要取值回车换行!
			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();
	}
});
这里是 codeplayer网站关于该方法的说明:

serializeArray()函数用于序列化一组表单元素,将表单内容编码为一个JavaScript数组serializeArray()函数常用于将表单内容序列化为JSON对象,以便于被编码为JSON格式的字符串。该函数会将可用于提交的每个表单控件封装成一个Object对象,该对象有name和value属性,对应该表单控件的name和value属性。然后将这些Object对象封装为一个数组并返回。该函数不会序列化不需要提交的表单控件,这和常规的表单提交行为是一致的。例如:不在<form>标签内的表单控件不会被提交、没有name属性的表单控件不会被提交、带有disabled属性的表单控件不会被提交、没有被选中的表单控件不会被提交。

我来说说这里面的几个值得注意的地方:

(1)之所以不再form标签里面的表单不会提交是因为这里面用到了elements属性,该属性是[object HTMLCollection]。一般的控件是没有的,如div元素等,但是form标签是有的,所以如果调用对象是form对象就会获取该form对象下所有的表单元素,如果是div,那么不管该元素下有多少控件都找不到,因为div就没有elements属性!这就是map方法做的,让调用对象每一个DOM元素都执行这个函数

(2)调用filter方法,该方法是对前面返回的DOM集合进行筛选的过程。这个过程是苛刻的。必须有name;必须非隐藏;必须可以提交的表单控件,如input|select|textarea|keygen;同时不能是特定的控件,如:submit|button|image|reset|file;同时对于checkbox/radio而言只会序列化checked存在的元素!常规的表单会提交带有name的控件标签,这个方法不会!

(3)最后一个map方法对上面的结果进行处理,得到一个名值对,键名是控件的name属性,键值是value值!同时对"\n"全部修改为"\r\n"

(4)至于serialize方法

serialize()函数用于序列化一组表单元素,将表单内容编码为用于提交的字符串serialize()函数常用于将表单内容序列化,以便用于AJAX提交。

该方法的作用是将表单元素name/value通过encodeURIComponent进行了编码,同时形成了name1=value1&name2=value2这种字符串了,因为内部调用了jQuery.param方法!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
我我很我很抱我很抱歉我很抱歉,我很抱歉,我我很抱歉,我作我很抱歉,我作为我很抱歉,我作为一个我很抱歉,我作为一个 AI我很抱歉,我作为一个 AI 我很抱歉,我作为一个 AI 语我很抱歉,我作为一个 AI 语言我很抱歉,我作为一个 AI 语言模我很抱歉,我作为一个 AI 语言模型我很抱歉,我作为一个 AI 语言模型,我很抱歉,我作为一个 AI 语言模型,无我很抱歉,我作为一个 AI 语言模型,无法我很抱歉,我作为一个 AI 语言模型,无法理我很抱歉,我作为一个 AI 语言模型,无法理解我很抱歉,我作为一个 AI 语言模型,无法理解你我很抱歉,我作为一个 AI 语言模型,无法理解你的我很抱歉,我作为一个 AI 语言模型,无法理解你的问题我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$("我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文和我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文和背我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文和背景我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文和背景信息我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文和背景信息,我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文和背景信息,让我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文和背景信息,让我我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文和背景信息,让我能我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文和背景信息,让我能够我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文和背景信息,让我能够更我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文和背景信息,让我能够更好我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文和背景信息,让我能够更好地我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文和背景信息,让我能够更好地帮我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文和背景信息,让我能够更好地帮助我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文和背景信息,让我能够更好地帮助你我很抱歉,我作为一个 AI 语言模型,无法理解你的问题。$.post("/user/login",$(" 是一个 JavaScript 代码片段,但我不能确定你的具体问题是什么。请提供更多上下文和背景信息,让我能够更好地帮助你。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值