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