用javascript我怎么能添加一个查询字符串参数的url,如果不存在或如果它存在,更新当前值?我使用jquery为我的客户端开发。


当前回答

您可以使用浏览器的本地URL API以一种相当简单的方式做到这一点,其中key和value分别是参数名和参数值。

const url = new URL(location.href);
url.searchParams.set(key, value);

history.pushState(null, '', url);

这将保留有关URL的所有内容,只更改或添加一个查询参数。如果您不希望它创建一个新的浏览器历史记录条目,也可以使用replaceState而不是pushState。

其他回答

使用ES6和jQuery将参数列表追加到现有url的代码:

class UrlBuilder {
    static appendParametersToUrl(baseUrl, listOfParams) {

        if (jQuery.isEmptyObject(listOfParams)) {
            return baseUrl;
        }

        const newParams = jQuery.param(listOfParams);

        let partsWithHash = baseUrl.split('#');
        let partsWithParams = partsWithHash[0].split('?');

        let previousParams = '?' + ((partsWithParams.length === 2) ? partsWithParams[1] + '&' : '');
        let previousHash = (partsWithHash.length === 2) ? '#' + partsWithHash[1] : '';

        return partsWithParams[0] + previousParams + newParams + previousHash;
    }
}

listOfParams是什么样的

const listOfParams = {
    'name_1': 'value_1',
    'name_2': 'value_2',
    'name_N': 'value_N',
};

用法示例:

    UrlBuilder.appendParametersToUrl(urlBase, listOfParams);

快速测试:

    url = 'http://hello.world';
    console.log('=> ', UrlParameters.appendParametersToUrl(url, null));
    // Output:  http://hello.world

    url = 'http://hello.world#h1';
    console.log('=> ', UrlParameters.appendParametersToUrl(url, null));
    // Output:  http://hello.world#h1

    url = 'http://hello.world';
    params = {'p1': 'v1', 'p2': 'v2'};
    console.log('=> ', UrlParameters.appendParametersToUrl(url, params));
    // Output: http://hello.world?p1=v1&p2=v2

    url = 'http://hello.world?p0=v0';
    params = {'p1': 'v1', 'p2': 'v2'};
    console.log('=> ', UrlParameters.appendParametersToUrl(url, params));
    // Output: http://hello.world?p0=v0&p1=v1&p2=v2

    url = 'http://hello.world#h1';
    params = {'p1': 'v1', 'p2': 'v2'};
    console.log('=> ', UrlParameters.appendParametersToUrl(url, params));
   // Output: http://hello.world?p1=v1&p2=v2#h1

    url = 'http://hello.world?p0=v0#h1';
    params = {'p1': 'v1', 'p2': 'v2'};
    console.log('=> ', UrlParameters.appendParametersToUrl(url, params));
    // Output: http://hello.world?p0=v0&p1=v1&p2=v2#h1

我已经扩展了解决方案,并将其与另一个我发现的替换/更新/删除基于用户输入的查询字符串参数,并将url锚纳入考虑。

不提供值将删除参数,提供值将添加/更新参数。如果没有提供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语句中删除声明哈希变量

使用此函数可以添加、删除和修改URL中的查询字符串参数

/**
@param String url
@param object param {key: value} query parameter
*/
function modifyURLQuery(url, param){
    var value = {};

    var query = String(url).split('?');

    if (query[1]) {
        var part = query[1].split('&');

        for (i = 0; i < part.length; i++) {
            var data = part[i].split('=');

            if (data[0] && data[1]) {
                value[data[0]] = data[1];
            }
        }
    }

    value = $.extend(value, param);

    // Remove empty value
    for (i in value){
        if(!value[i]){
            delete value[i];
        }
    }

    // Return url with modified parameter
    if(value){
        return query[0] + '?' + $.param(value);
    } else {
        return query[0];
    }
}

添加新的和修改现有参数的url

var new_url = modifyURLQuery("http://google.com?foo=34", {foo: 50, bar: 45});
// Result: http://google.com?foo=50&bar=45

删除现有的

var new_url = modifyURLQuery("http://google.com?foo=50&bar=45", {bar: null});
// Result: http://google.com?foo=50

下面是使用锚HTML元素的内置属性的另一种方法:

处理多值参数。 没有修改#片段或查询字符串本身以外的任何内容的风险。 可能会更容易读?但是它更长。

var a = document.createElement('a'), getHrefWithUpdatedQueryString = function(param, value) { return updatedQueryString(window.location.href, param, value); }, updatedQueryString = function(url, param, value) { /* A function which modifies the query string by setting one parameter to a single value. Any other instances of parameter will be removed/replaced. */ var fragment = encodeURIComponent(param) + '=' + encodeURIComponent(value); a.href = url; if (a.search.length === 0) { a.search = '?' + fragment; } else { var didReplace = false, // Remove leading '?' parts = a.search.substring(1) // Break into pieces .split('&'), reassemble = [], len = parts.length; for (var i = 0; i < len; i++) { var pieces = parts[i].split('='); if (pieces[0] === param) { if (!didReplace) { reassemble.push('&' + fragment); didReplace = true; } } else { reassemble.push(parts[i]); } } if (!didReplace) { reassemble.push('&' + fragment); } a.search = reassemble.join('&'); } return a.href; };

这是一个简短的版本

使用或不使用给定参数查询 使用多个参数值查询 包含散列的查询

代码:

var setQueryParameter = function(uri, key, value) {
  var re = new RegExp("([?&])("+ key + "=)[^&#]*", "g");
  if (uri.match(re)) 
    return uri.replace(re, '$1$2' + value);

  // need to add parameter to URI
  var paramString = (uri.indexOf('?') < 0 ? "?" : "&") + key + "=" + value;
  var hashIndex = uri.indexOf('#');
  if (hashIndex < 0)
    return uri + paramString;
  else
    return uri.substring(0, hashIndex) + paramString + uri.substring(hashIndex);
}

正则表达式描述可以在这里找到。

注意:这个解决方案是基于@amateur的答案,但是有很多改进。