From f91b944cabf7be9aadb40ffe35fce76b50f5f25f Mon Sep 17 00:00:00 2001 From: John Resig Date: Mon, 25 Jan 2010 00:46:03 -0500 Subject: [PATCH] Objects with length properties weren't getting serialized properly by jQuery.param(). Fixes #5862. --- src/ajax.js | 81 ++++++++++++++++++++++++----------------------- test/unit/ajax.js | 13 ++++++++ 2 files changed, 54 insertions(+), 40 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index 754de09a..ee52ed82 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -603,7 +603,6 @@ jQuery.extend({ // Serialize an array of form elements or a set of // key/values into a query string param: function( a, traditional ) { - var s = []; // Set traditional to true for jQuery <= 1.3.2 behavior. @@ -611,12 +610,6 @@ jQuery.extend({ traditional = jQuery.ajaxSettings.traditional; } - function add( 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); - } - // If an array was passed in, assume that it is an array of form elements. if ( jQuery.isArray(a) || a.jquery ) { // Serialize the form elements @@ -627,41 +620,49 @@ jQuery.extend({ } else { // If traditional, encode the "old" way (the way 1.3.2 or older // did it), otherwise encode params recursively. - jQuery.each( a, function buildParams( prefix, obj ) { - - if ( jQuery.isArray(obj) ) { - // Serialize array item. - jQuery.each( obj, function( i, v ) { - if ( traditional ) { - // Treat each array item as a scalar. - add( prefix, v ); - } else { - // If array item is non-scalar (array or object), encode its - // numeric index to resolve deserialization ambiguity issues. - // Note that rack (as of 1.0.0) can't currently deserialize - // nested arrays properly, and attempting to do so may cause - // a server error. Possible fixes are to modify rack's - // deserialization algorithm or to provide an option or flag - // to force array serialization to be shallow. - buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v ); - } - }); - - } else if ( !traditional && obj != null && typeof obj === "object" ) { - // Serialize object item. - jQuery.each( obj, function( k, v ) { - buildParams( prefix + "[" + k + "]", v ); - }); - - } else { - // Serialize scalar item. - add( prefix, obj ); - } - }); + for ( var prefix in a ) { + buildParams( prefix, a[prefix] ); + } } - + // Return the resulting serialization return s.join("&").replace(r20, "+"); - } + function buildParams( prefix, obj ) { + if ( jQuery.isArray(obj) ) { + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional ) { + // Treat each array item as a scalar. + add( prefix, v ); + } else { + // If array item is non-scalar (array or object), encode its + // numeric index to resolve deserialization ambiguity issues. + // Note that rack (as of 1.0.0) can't currently deserialize + // nested arrays properly, and attempting to do so may cause + // a server error. Possible fixes are to modify rack's + // deserialization algorithm or to provide an option or flag + // to force array serialization to be shallow. + buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v ); + } + }); + + } else if ( !traditional && obj != null && typeof obj === "object" ) { + // Serialize object item. + jQuery.each( obj, function( k, v ) { + buildParams( prefix + "[" + k + "]", v ); + }); + + } else { + // Serialize scalar item. + add( prefix, obj ); + } + } + + function add( 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); + } + } }); diff --git a/test/unit/ajax.js b/test/unit/ajax.js index cd3aba0a..775523e5 100644 --- a/test/unit/ajax.js +++ b/test/unit/ajax.js @@ -979,6 +979,19 @@ test("jQuery.getJSON(String, Function) - JSON object with absolute url to local }); }); +test("jQuery.post - data", function() { + expect(2); + stop(); + + jQuery.post(url("data/name.php"), {xml: "5-2", length: 3}, function(xml){ + jQuery('math', xml).each(function() { + equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' ); + equals( jQuery('result', this).text(), '3', 'Check for XML' ); + }); + start(); + }); +}); + test("jQuery.post(String, Hash, Function) - simple with xml", function() { expect(4); stop();