如何添加或更新查询字符串参数?

IT技术 javascript jquery query-string
2021-01-11 14:53:16

使用 javascript 如何将查询字符串参数添加到 url 如果不存在或如果存在,更新当前值?我正在使用 jquery 进行客户端开发。

6个回答

我编写了以下函数来完成我想要实现的目标:

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
  var separator = uri.indexOf('?') !== -1 ? "&" : "?";
  if (uri.match(re)) {
    return uri.replace(re, '$1' + key + "=" + value + '$2');
  }
  else {
    return uri + separator + key + "=" + value;
  }
}
通过var在分隔符声明之前添加将分隔符变量范围限制为局部函数
2021-03-10 14:53:16
好的!@greg:你是对的 - 请参阅我对应该处理哈希标签的变体的回答
2021-03-15 14:53:16
2021-03-16 14:53:16
我认为,您应该value = encodeURIComponent(value);在第一行添加,否则无法正确转义换行符。
2021-04-02 14:53:16
当 URI 中有散列时,此答案不起作用 - 查询字符串必须放在散列之前,否则它们不会发送到服务器。jsfiddle.net/4yXzR
2021-04-08 14:53:16

更新(2020 年):所有现代浏览器现在都支持URLSearchParams

URLSearchParams实用程序可以与组合是这个有用的window.location.search例如:

if ('URLSearchParams' in window) {
    var searchParams = new URLSearchParams(window.location.search);
    searchParams.set("foo", "bar");
    window.location.search = searchParams.toString();
}

Nowfoo已经设置为bar不管它是否已经存在。

但是,上面的赋值window.location.search将导致页面加载,所以如果这不是可取的,请使用History API,如下所示:

if ('URLSearchParams' in window) {
    var searchParams = new URLSearchParams(window.location.search)
    searchParams.set("foo", "bar");
    var newRelativePathQuery = window.location.pathname + '?' + searchParams.toString();
    history.pushState(null, '', newRelativePathQuery);
}

现在您无需编写自己的正则表达式或逻辑来处理可能存在的查询字符串。

然而,浏览器支持很差,因为它目前处于实验阶段,仅在最新版本的 Chrome、Firefox、Safari、iOS Safari、Android 浏览器、Android Chrome 和 Opera 中使用。如果您决定使用polyfill,请与polyfill一起使用。

完美的答案,但是当 url 中存在主题标签时,它不会处理用例。将哈希简单附加到末尾就newRelativePathQuery可以解决问题:var newRelativePathQuery = window.location.pathname + '?' + searchParams.toString() + window.location.hash;
2021-03-11 14:53:16
我发现 URL 比 URLSearchParams 更容易使用 const url = new URL(window.location); url.searchParams.set("foo", "bar"); window.location = url;
2021-03-13 14:53:16
2019 年更新:浏览器支持现在适用于除 IE 和一些小型移动浏览器之外的大多数浏览器。ungap 的新 pollyfill 很容易涵盖:github.com/ungap/url-search-params
2021-04-01 14:53:16
波利填充,不好, Unable to set property '__URLSearchParams__:0.8503766759030615' of undefined or null reference 在 ie11 上你会得到那个错误。如果它不能作为后备,它就不是 pollyfill。
2021-04-05 14:53:16

我扩展了该解决方案并将其与另一个我发现的解决方案相结合,以根据用户输入替换/更新/删除查询字符串参数并考虑 urls 锚点。

不提供值将删除参数,提供一个将添加/更新参数。如果没有提供 URL,它将从 window.location 抓取

function UpdateQueryString(key, value, url) {
    if (!url) url = window.location.href;
    var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"),
        hash;

    if (re.test(url)) {
        if (typeof value !== 'undefined' && value !== null) {
            return url.replace(re, '$1' + key + "=" + value + '$2$3');
        } 
        else {
            hash = url.split('#');
            url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
            if (typeof hash[1] !== 'undefined' && hash[1] !== null) {
                url += '#' + hash[1];
            }
            return url;
        }
    }
    else {
        if (typeof value !== 'undefined' && value !== null) {
            var separator = url.indexOf('?') !== -1 ? '&' : '?';
            hash = url.split('#');
            url = hash[0] + separator + key + '=' + value;
            if (typeof hash[1] !== 'undefined' && hash[1] !== null) {
                url += '#' + hash[1];
            }
            return url;
        }
        else {
            return url;
        }
    }
}

更新

删除查询字符串中的第一个参数时出现错误,我重新编写了正则表达式并进行了测试以包含修复程序。

第二次更新

正如@JarónBarends 所建议的那样 - 调整值检查以检查 undefined 和 null 以允许设置 0 值

第三次更新

有一个错误,在主题标签之前直接删除查询字符串变量会丢失已修复的主题标签符号

第四次更新

感谢@rooby 指出第一个 RegExp 对象中的正则表达式优化。由于使用@YonatanKarni 发现的 (\?|&) 问题,将初始正则表达式设置为 ([?&])

第五次更新

删除在 if/else 语句中声明的哈希变量

除了我是强迫症之外,这并不重要,但是变量hash被声明了两次;)
2021-03-14 14:53:16
在 chrome 版本 31.0.1650.63 中创建正则表达式时出现“无效的常规异常/无效组”异常,通过将开头返回为“([?&])”来解决
2021-03-27 14:53:16
有趣的是如何从原始解决方案中继承过来 - 也可以使用 (\?|&)
2021-04-02 14:53:16
在正则表达式中 ([?|&]) 真的应该是 ([?&])
2021-04-04 14:53:16
value当您将它们的值设置为 0 时,仅检查 的“真实性”将导致它从查询字符串中删除变量。因此,if (value) {}您应该使用if (typeOf value !== 'undefined' && value !== null) {}
2021-04-05 14:53:16

基于@amateur 的回答(现在结合了@j_walker_dev 评论中的修复),但考虑到关于 url 中哈希标签的评论,我使用以下内容:

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");
  if (uri.match(re)) {
    return uri.replace(re, '$1' + key + "=" + value + '$2');
  } else {
    var hash =  '';
    if( uri.indexOf('#') !== -1 ){
        hash = uri.replace(/.*#/, '#');
        uri = uri.replace(/#.*/, '');
    }
    var separator = uri.indexOf('?') !== -1 ? "&" : "?";    
    return uri + separator + key + "=" + value + hash;
  }
}

编辑以修复[?|&]正则表达式,这当然应该[?&]在评论中指出

编辑:支持删除URL 参数的替代版本我已用作value === undefined表示移除的方式。可以根据需要使用value === false甚至单独的输入参数。

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");
  if( value === undefined ) {
    if (uri.match(re)) {
    return uri.replace(re, '$1$2').replace(/[?&]$/, '').replaceAll(/([?&])&+/g, '$1').replace(/[?&]#/, '#');
  } else {
    return uri;
  }
  } else {
    if (uri.match(re)) {
      return uri.replace(re, '$1' + key + "=" + value + '$2');
  } else {
    var hash =  '';
    if( uri.indexOf('#') !== -1 ){
        hash = uri.replace(/.*#/, '#');
        uri = uri.replace(/#.*/, '');
    }
    var separator = uri.indexOf('?') !== -1 ? "&" : "?";    
    return uri + separator + key + "=" + value + hash;
    }
  }
}

https://jsfiddle.net/cdt16wex/查看它的实际效果

干净多了。仅供可以拥有“?”的角度 ui-router 用户使用。在哈希中也是如此。将该var separator移动到返回值的正上方修复了一个带有“/app#/cool?fun=true”的错误。即使还没有真正的查询字符串参数,这也会选择“&”作为分隔符。只有客户。
2021-03-24 14:53:16
是的,"([?|&])"不好。请将此修复为var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");(其他方式的一个很好的扩展!)
2021-03-27 14:53:16
谢谢,很棒的编辑。在 JSFiddle 中,如果我反复删除和添加参数,最终 URL 看起来是这样的:https://www.example.com/?&&&&#baz如果我只删除foo参数,我会得到这个:https://www.example.com/?&bar=2#baz两者都有?和 & 在那里,即使只有一个参数。
2021-04-03 14:53:16
正如在对其他答案的评论中指出的那样,[?|&]应该只是[?&](否则会匹配|)。
2021-04-09 14:53:16
好的,抱歉,var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");不行,第二个可以
2021-04-09 14:53:16

这是我的图书馆:https : //github.com/Mikhus/jsurl

var u = new Url;
u.query.param='value'; // adds or replaces the param
alert(u)