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


当前回答

我知道这是相当旧的,但我想把我的工作版本在这里。

function addOrUpdateUrlParam(uri, paramKey, paramVal) { var re = new RegExp("([?&])" + paramKey + "=[^&#]*", "i"); if (re.test(uri)) { uri = uri.replace(re, '$1' + paramKey + "=" + paramVal); } else { var separator = /\?/.test(uri) ? "&" : "?"; uri = uri + separator + paramKey + "=" + paramVal; } return uri; } jQuery(document).ready(function($) { $('#paramKey,#paramValue').on('change', function() { if ($('#paramKey').val() != "" && $('#paramValue').val() != "") { $('#uri').val(addOrUpdateUrlParam($('#uri').val(), $('#paramKey').val(), $('#paramValue').val())); } }); }); <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input style="width:100%" type="text" id="uri" value="http://www.example.com/text.php"> <label style="display:block;">paramKey <input type="text" id="paramKey"> </label> <label style="display:block;">paramValue <input type="text" id="paramValue"> </label>

说明修改后的@elreimundo

其他回答

感谢现代javascript, node.js和浏览器的支持,我们可以摆脱第三方库的漩涡(jquery, query-string等)和DRY自己。

下面是javascript(node.js)和typescript版本的函数,用于添加或更新给定url的查询参数:

Javascript

const getUriWithParam = (baseUrl, params) => { const Url = new URL(baseUrl); const urlParams = new URLSearchParams(Url.search); for (const key in params) { if (params[key] !== undefined) { urlParams.set(key, params[key]); } } Url.search = urlParams.toString(); return Url.toString(); }; console.info('expected: https://example.com/?foo=bar'); console.log(getUriWithParam("https://example.com", {foo: "bar"})); console.info('expected: https://example.com/slug?foo=bar#hash'); console.log(getUriWithParam("https://example.com/slug#hash", {foo: "bar"})); console.info('expected: https://example.com/?bar=baz&foo=bar'); console.log(getUriWithParam("https://example.com?bar=baz", {foo: "bar"})); console.info('expected: https://example.com/?foo=baz&bar=baz'); console.log(getUriWithParam("https://example.com?foo=bar&bar=baz", {foo: "baz"}));

打印稿


const getUriWithParam = (
  baseUrl: string,
  params: Record<string, any>
): string => {
  const Url = new URL(baseUrl);
  const urlParams: URLSearchParams = new URLSearchParams(Url.search);
  for (const key in params) {
    if (params[key] !== undefined) {
      urlParams.set(key, params[key]);
    }
  }
  Url.search = urlParams.toString();
  return Url.toString();
};

对于React Native

URL在React Native中没有实现。所以你必须事先安装react-native-url-polyfill。

对于对象参数

请看这个答案中的第二个解决方案

我已经扩展了解决方案,并将其与另一个我发现的替换/更新/删除基于用户输入的查询字符串参数,并将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语句中删除声明哈希变量

这样做的目的是:

function updateQueryString(url, key, value) {
    var arr =  url.split("#");
    var url = arr[0];
    var fragmentId = arr[1];
    var updatedQS = "";
    if (url.indexOf("?") == -1) {
        updatedQS = encodeURIComponent(key) + "=" + encodeURIComponent(value);
    }
    else {
        updatedQS = addOrModifyQS(url.substring(url.indexOf("?") + 1), key, value); 
    }
    url = url.substring(0, url.indexOf("?")) + "?" + updatedQS;
    if (typeof fragmentId !== 'undefined') {
        url = url + "#" + fragmentId;
    }
    return url;
}

function addOrModifyQS(queryStrings, key, value) {
    var oldQueryStrings = queryStrings.split("&");
    var newQueryStrings = new Array();
    var isNewKey = true;
    for (var i in oldQueryStrings) {
        var currItem = oldQueryStrings[i];
        var searchKey = key + "=";
        if (currItem.indexOf(searchKey) != -1) {
            currItem = encodeURIComponent(key) + "=" + encodeURIComponent(value);
            isNewKey = false;
        }
        newQueryStrings.push(currItem);
    }
    if (isNewKey) {
        newQueryStrings.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
    }
    return newQueryStrings.join("&");
}   

使用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

下面是我的方法:location.params()函数(如下所示)可以用作getter或setter。例子:

假设URL是http://example.com/?foo=bar&baz#some-hash,

Location.params()将返回一个包含所有查询参数的对象:{foo: 'bar', baz: true}。 Location.params ('foo')将返回'bar'。 的位置。params({foo: undefined, hello: 'world', test: true})会将URL更改为http://example.com/?baz&hello=world&test#some-hash。

下面是params()函数,它可以被选择性地分配给窗口。位置的对象。

location.params = function(params) {
  var obj = {}, i, parts, len, key, value;

  if (typeof params === 'string') {
    value = location.search.match(new RegExp('[?&]' + params + '=?([^&]*)[&#$]?'));
    return value ? value[1] : undefined;
  }

  var _params = location.search.substr(1).split('&');

  for (i = 0, len = _params.length; i < len; i++) {
    parts = _params[i].split('=');
    if (! parts[0]) {continue;}
    obj[parts[0]] = parts[1] || true;
  }

  if (typeof params !== 'object') {return obj;}

  for (key in params) {
    value = params[key];
    if (typeof value === 'undefined') {
      delete obj[key];
    } else {
      obj[key] = value;
    }
  }

  parts = [];
  for (key in obj) {
    parts.push(key + (obj[key] === true ? '' : '=' + obj[key]));
  }

  location.search = parts.join('&');
};