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


当前回答

Window.location.search是读/写的。

然而,修改查询字符串将重定向您所在的页面,并导致从服务器刷新。

如果您试图做的是维护客户端状态(并可能使其可书签),您将希望修改URL散列而不是查询字符串,这将使您保持在同一页面(window.location。哈希是读/写)。像twitter.com这样的网站就是这样做的。

你还想让后退按钮工作,你必须将javascript事件绑定到哈希更改事件,一个很好的插件是http://benalman.com/projects/jquery-hashchange-plugin/

其他回答

下面是使用锚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; };

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

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

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

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

我从这里得出的结论(与“使用严格”相容;并不真正使用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()));
});

感谢现代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)