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

其他回答

根据@ellemayo给出的答案,我提出了以下解决方案,如果需要,可以禁用散列标签:

function updateQueryString(key, value, options) {
    if (!options) options = {};

    var url = options.url || location.href;
    var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"), hash;

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

    if ((typeof options.hash === 'undefined' || options.hash) &&
        typeof hash[1] !== 'undefined' && hash[1] !== null)
        url += '#' + hash[1];
    return url;
}

这样叫它:

updateQueryString('foo', 'bar', {
    url: 'http://my.example.com#hash',
    hash: false
});

结果:

http://my.example.com?foo=bar

我从这里得出的结论(与“使用严格”相容;并不真正使用jQuery):

function decodeURIParams(query) {
  if (query == null)
    query = window.location.search;
  if (query[0] == '?')
    query = query.substring(1);

  var params = query.split('&');
  var result = {};
  for (var i = 0; i < params.length; i++) {
    var param = params[i];
    var pos = param.indexOf('=');
    if (pos >= 0) {
        var key = decodeURIComponent(param.substring(0, pos));
        var val = decodeURIComponent(param.substring(pos + 1));
        result[key] = val;
    } else {
        var key = decodeURIComponent(param);
        result[key] = true;
    }
  }
  return result;
}

function encodeURIParams(params, addQuestionMark) {
  var pairs = [];
  for (var key in params) if (params.hasOwnProperty(key)) {
    var value = params[key];
    if (value != null) /* matches null and undefined */ {
      pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(value))
    }
  }
  if (pairs.length == 0)
    return '';
  return (addQuestionMark ? '?' : '') + pairs.join('&');
}

//// alternative to $.extend if not using jQuery:
// function mergeObjects(destination, source) {
//   for (var key in source) if (source.hasOwnProperty(key)) {
//     destination[key] = source[key];
//   }
//   return destination;
// }

function navigateWithURIParams(newParams) {
  window.location.search = encodeURIParams($.extend(decodeURIParams(), newParams), true);
}

使用示例:

// add/update parameters
navigateWithURIParams({ foo: 'bar', boz: 42 });

// remove parameter
navigateWithURIParams({ foo: null });

// submit the given form by adding/replacing URI parameters (with jQuery)
$('.filter-form').submit(function(e) {
  e.preventDefault();
  navigateWithURIParams(decodeURIParams($(this).serialize()));
});

下面是我的方法: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('&');
};

感谢现代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 API 可以添加、更新、获取或删除吗 期望在散列之后的查询字符串,例如对于单页应用程序

function queryParam(options = {}) { var defaults = { method: 'set', url: window.location.href, key: undefined, value: undefined, } for (var prop in defaults) { options[prop] = typeof options[prop] !== 'undefined' ? options[prop] : defaults[prop] } const existing = (options.url.lastIndexOf('?') > options.url.lastIndexOf('#')) ? options.url.substr(options.url.lastIndexOf('?') + 1) : '' const query = new URLSearchParams(existing) if (options.method === 'set') { query.set(options.key, options.value) return `${options.url.replace(`?${existing}`, '')}?${query.toString()}` } else if (options.method === 'get') { const val = query.get(options.key) let result = val === null ? val : val.toString() return result } else if (options.method === 'delete') { query.delete(options.key) let result = `${options.url.replace(`?${existing}`, '')}?${query.toString()}` const lastChar = result.charAt(result.length - 1) if (lastChar === '?') { result = `${options.url.replace(`?${existing}`, '')}` } return result } } // Usage: let url = 'https://example.com/sandbox/#page/' url = queryParam({ url, method: 'set', key: 'my-first-param', value: 'me' }) console.log(url) url = queryParam({ url, method: 'set', key: 'my-second-param', value: 'you' }) console.log(url) url = queryParam({ url, method: 'set', key: 'my-second-param', value: 'whomever' }) console.log(url) url = queryParam({ url, method: 'delete', key: 'my-first-param' }) console.log(url) const mySecondParam = queryParam({ url, method: 'get', key: 'my-second-param', }) console.log(mySecondParam) url = queryParam({ url, method: 'delete', key: 'my-second-param' }) console.log(url)