如何使用jQuery操纵查询字符串

8
我有一个select下拉列表,其中id映射到值。 在onChange事件中,我想要重定向到相同的url,但附加到查询字符串中的'id=value'。
如何检查此'id'选项是否已存在于查询字符串中(我不希望有多个值),并根据需要替换/追加。
如何检查查询字符串中是否已经存在'?',如果不存在,则将其附加到url上。
使用jquery有没有简单的方法来实现这个?
它必须在幕后执行类似于$().ajax(url,{options})调用的操作。 我希望我只需执行$().redirect( url, { id : $(this).val() })或类似操作即可。
提前感谢您。
注意:此页面可能会传递几个不同的查询选项(这些选项设置其他表单选项的默认值),因此替换整个查询字符串不是一个选项。
<html>
<head><script type="text/javascript" src="/jquery-1.3.2.min.js"></script></head>
<body>
  <script>
    $(function(){                                                                                                                                         
        $('#selector').change(function(){                                                                                                                 
            // problem if 'id' option already exists
            var url = location.href + '?;id=' + $(this).val();                                                                                            
            location.assign( url );
        });                                                                                                                                               
    });                                                                                                                                                   
  </script>

  <a href="#" onclick="location.assign( location.pathname )">reset</a>                                                                                      
  <form>                                                                                                                                                    
    <select id='selector' name='id'>                                                                                                                      
        <option value='1'>one</option>                                                                                                                    
        <option value='2'>two</option>                                                                                                                    
        <option value='3'>three</option>                                                                                                                  
    </select>                                                                                                                                             
  </form>
</body>
</html>

可能是JavaScript对象的查询字符串编码的重复问题。 - Sindre Sorhus
6个回答

10

最终我选择使用RegExp匹配来覆盖选项。jQuery.param接受一个哈希并将其序列化为查询字符串,但它不提供反向操作(将查询字符串分解为哈希)。

// put function into jQuery namespace
jQuery.redirect = function(url, params) {

    url = url || window.location.href || '';
    url =  url.match(/\?/) ? url : url + '?';

    for ( var key in params ) {
        var re = RegExp( ';?' + key + '=?[^&;]*', 'g' );
        url = url.replace( re, '');
        url += ';' + key + '=' + params[key]; 
    }  
    // cleanup url 
    url = url.replace(/[;&]$/, '');
    url = url.replace(/\?[;&]/, '?'); 
    url = url.replace(/[;&]{2}/g, ';');
    // $(location).attr('href', url);
    window.location.replace( url ); 
};

然后在HTML中

$('#selector').change(function(){ 
   $.redirect( location.href, { id : $(this).val() })
})
感谢所有回复的人。

7

基于CoffeeMonster的回答:

当location.href包含哈希部分时存在问题:

www.example.com#hash 变成 www.example.com#hash?id=whatever,导致服务器无法解释 ?id=whatever

通过删除URL的哈希部分来解决它:url.split("#")[0];

// put function into jQuery namespace
jQuery.redirect = function(url, params) {

    url = url || window.location.href || '';
    url = url.split("#")[0];
    url =  url.match(/\?/) ? url : url + '?';

    for ( var key in params ) {
        var re = RegExp( ';?' + key + '=?[^&;]*', 'g' );
        url = url.replace( re, '');
        url += ';' + key + '=' + params[key]; 
    }  
    // cleanup url 
    url = url.replace(/[;&]$/, '');
    url = url.replace(/\?[;&]/, '?'); 
    url = url.replace(/[;&]{2}/g, ';');
    // $(location).attr('href', url);
    window.location.replace( url ); 
};

现在,www.example.com#hash 变成了 www.example.com?id=whatever

1
现在,为了获得额外的积分,请将哈希重新附加到URL的末尾。 :-) - Martijn Pieters

7

设置 window.location.search 将更新 URL 的查询字符串(如果值已存在,则会覆盖)

$('#selector').change(function(){  
  window.location.search = "id=" + $(this).val();
}); 

用什么浏览器?你的HTML和JS是什么样子的? - Alpha Codemonkey
抱歉,我误将.search视为“搜索”查询字符串参数。实际上,search指的是DOM位置对象中的整个查询字符串。 - crizCraig

2
这个功能非常好用:
jQuery.redirect = function( url ) {
   window.location.replace( url );  
};
$( "#selector" ).change( function() {
    var href = window.location.href.substring( 0, window.location.href.indexOf( '?' ) );
    $.redirect( href + '?id=' + $( this ).val() );
} );

1

尝试使用split函数:

var url = location.href.split('?')[0] + '?;id=' + $(this).val();

split 函数将字符串按照指定的分隔符(如'?')拆分成一个列表,并在结果列表中删除该分隔符。


0

我怀疑所谓的解决方法在特定的变量名称上不起作用。尤其是这一行:

RegExp( ';?' + key + '=?[^&;]*', 'g' )

如果关键字是查询字符串中其他位置存在的字符序列,那么该出现位置也将被错误地替换(尝试一个字母,例如 'a')。这是因为正则表达式保留了字符串边界(前导 ';' 和尾随 '=' 都是可选的)。也许更好的表达式应该是这样的:
RegExp( '[;&]' + key + '=?[^&;]*', 'g' )

虽然我还没有测试过它。


不错的错误发现! 刚刚检查了我的代码,我正在传递 client_id=12;project_id=45; 等等,但是我看到只有 id= 就很容易出问题。 我想我会使用类似于 RegExp( '[;&]?\b' ... ) 的东西。 等我上班后再测试一下。谢谢。 - CoffeeMonster

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