覆盖jQuery.param函数

8

我在使用jQuery.param函数时遇到了问题。 jQuery使用“+”而不是“%20”来对空格进行URL编码。

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

返回值为"test=tester+2"

所以我考虑重写这个核心函数:

(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));

然而,这个方法失败了... $.param 没有被覆盖。

有什么想法是错的吗?

谢谢!

编辑:我的解决方案(因为我是新用户,显然8小时内不能回答自己的问题(为什么?))

使用 ThiefMaster 的解决方案后,我仍然有一个问题,即 buildParams 未定义。 我通过调用旧函数,然后将 + 替换为 %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);

3
如果你真的需要这个功能,最好创建一个包装器(wrapper),这个包装器使用原始函数并将 '+' 替换为 '%20',而不是复制和粘贴一个庞大的函数做一个小小的修改。 - ThiefMaster
我通过使用jQuery AJAX间接地使用$.param函数。在发送XHR之前,我无法再次将+替换为%20。 但是,我确实可以通过应用旧函数然后将+替换为%20来覆盖它。 - Chielus
感谢您更新了解决方案,它很有效!现在只希望它不会与其他东西产生冲突。 - IsmailS
我不同意你应该用%20替换+,因为值中可能有一个+字符,它并不意味着是一个空格。这不是一个安全的解决方案。覆盖该方法会更加安全。 - Filipiz
3个回答

3
您需要使用$.param而不是$.fn.param(这将是要在jQuery对象上调用的函数,例如$(...).param())。

2

虽然这是一个旧帖子,但为了记录知识,请允许我翻译一下。如果要替换使用$.param()时留下的'+',请考虑执行以下操作:

(使用您提供的代码)

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

这将导致:

test = tester 2

希望对某些人有所帮助。


0
“re-replace”修复也可以通过在ajax设置对象中使用“beforeSend”来实现:
{ beforeSend: function (request, settings) { settings.data = settings.data.replace(/\+/g, "%20"); } }

这种方法适用于那些实际上不想改变 $.param() 原始行为的情况(例如,如果您想在 URL 中使用 "+",但在 POST 数据中使用 "%20")。

[编辑,因为我记得 string.replace() 只会匹配一次,除非它是带有 g 标志的正则表达式对象。]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接