admin管理员组

文章数量:1401640

I have a problem with the jQuery.param function. jQuery uses + instead of %20 to URL-encode spaces

var obje = {
    'test': 'tester 2'
}
console.log($.param(obje));

returns "test=tester+2"

so I thought about overriding this core function:

(function($){
        $.fn.param = function( a, traditional ) {
            console.log('custom $.param');
            var s = [],
                add = function( 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 );
                };

            // Set traditional to true for jQuery <= 1.3.2 behavior.
            if ( traditional === undefined ) {
                traditional = jQuery.ajaxSettings.traditional;
            }

            // If an array was passed in, assume that it is an array of form elements.
            if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
                // Serialize the form elements
                jQuery.each( a, function() {
                    add( this.name, this.value );
                } );

            } else {
                // If traditional, encode the "old" way (the way 1.3.2 or older
                // did it), otherwise encode params recursively.
                for ( var prefix in a ) {
                    buildParams( prefix, a[ prefix ], traditional, add );
                }
            }
            return s.join("&");
            // Return the resulting serialization
            //return s.join( "&" ).replace( r20, "+" );
        };
    })(jQuery);
var obje = {
    'test': 'tester 2'
}
console.log($.param(obje));

This fails however.. The $.param isn't overridden.

Any idea what can be wrong?

Thanks!

Edit: my solution (because I'm a new user I appearently may not answer my own question in 8 hours (Why is that?))

With the solution of ThiefMaster I still had the problem that buildParams is undefined. I solved this by calling the old function and then replacing the + back to %20

// modification of the jQuery.param function: spaces are encoded by jQuery.param with + instead of %20. replace these back to %20
(function($, oldFunction){
    $.param = function( a, traditional ) {
        var s = oldFunction.apply(oldFunction,[a,traditional]);
        // Return the resulting serialization
        return s.replace( '+', '%20' );
    };
})(jQuery,jQuery.param);

I have a problem with the jQuery.param function. jQuery uses + instead of %20 to URL-encode spaces

var obje = {
    'test': 'tester 2'
}
console.log($.param(obje));

returns "test=tester+2"

so I thought about overriding this core function:

(function($){
        $.fn.param = function( a, traditional ) {
            console.log('custom $.param');
            var s = [],
                add = function( 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 );
                };

            // Set traditional to true for jQuery <= 1.3.2 behavior.
            if ( traditional === undefined ) {
                traditional = jQuery.ajaxSettings.traditional;
            }

            // If an array was passed in, assume that it is an array of form elements.
            if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
                // Serialize the form elements
                jQuery.each( a, function() {
                    add( this.name, this.value );
                } );

            } else {
                // If traditional, encode the "old" way (the way 1.3.2 or older
                // did it), otherwise encode params recursively.
                for ( var prefix in a ) {
                    buildParams( prefix, a[ prefix ], traditional, add );
                }
            }
            return s.join("&");
            // Return the resulting serialization
            //return s.join( "&" ).replace( r20, "+" );
        };
    })(jQuery);
var obje = {
    'test': 'tester 2'
}
console.log($.param(obje));

This fails however.. The $.param isn't overridden.

Any idea what can be wrong?

Thanks!

Edit: my solution (because I'm a new user I appearently may not answer my own question in 8 hours (Why is that?))

With the solution of ThiefMaster I still had the problem that buildParams is undefined. I solved this by calling the old function and then replacing the + back to %20

// modification of the jQuery.param function: spaces are encoded by jQuery.param with + instead of %20. replace these back to %20
(function($, oldFunction){
    $.param = function( a, traditional ) {
        var s = oldFunction.apply(oldFunction,[a,traditional]);
        // Return the resulting serialization
        return s.replace( '+', '%20' );
    };
})(jQuery,jQuery.param);
Share Improve this question edited Apr 27, 2011 at 15:35 Chielus asked Apr 27, 2011 at 13:27 ChielusChielus 6328 silver badges19 bronze badges 4
  • 3 If you really need this, better create a wrapper which uses the original function and then replaces '+' with '%20' instead of copying&pasting a huge function for a minor change. – ThiefMaster Commented Apr 27, 2011 at 13:30
  • I use the $.param function indirectly by working with jQuery AJAX. I can't replace + with %20 again before sending the XHR. However, I could indeed override it with applying the old function and then replacing + with %20 – Chielus Commented Apr 27, 2011 at 15:18
  • Thanks for update on solution that worked for you. It works! Now just hoping that it won't conflict with something else. – IsmailS Commented Nov 26, 2013 at 7:53
  • I dont agree you should replace + with %20 because there could be a + character that is not intended to be a space on the values. It is not a safe solution. Overwriting the method is much more secure. – Filipiz Commented Sep 19, 2014 at 16:40
Add a ment  | 

3 Answers 3

Reset to default 3

You need to use $.param instead of $.fn.param (which would be a function to call on a jQuery object, e.g. $(...).param()).

Old post I know, but for the sake of recorded knowledge. To replace the '+' left behind when using $.param(), consider doing the following:

(Using the code you provided)

var obje = {
'test': 'tester 2'
}
console.log($.param(obje).replace(/\+/g, "%20"));

That will result in: test = tester 2

Hope this helps someone.

The "re-replace" fix may also be implemented by using "beforeSend" in the ajax settings object:

{ beforeSend: function (request, settings) { settings.data = settings.data.replace(/\+/g, "%20"); } }

This approach is suitable for cases where you don't actually want to alter $.param()'s original behavior (for example, if you want "+" in URLs but "%20" for POST data).

[Edited because I remembered that string.replace() will only match once unless it's a regex object with the g flag.]

本文标签: javascriptoverriding the jqueryparam functionStack Overflow