简体   繁体   English

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

[英]How can I add or update a query string parameter?

With javascript how can I add a query string parameter to the url if not present or if it present, update the current value?使用 javascript 如何将查询字符串参数添加到 url 如果不存在或存在,则更新当前值? I am using jquery for my client side development.我正在使用 jquery 进行客户端开发。

I wrote the following function which accomplishes what I want to achieve:我编写了以下函数来完成我想要实现的目标:

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;
  }
}

Update (2020): URLSearchParams is now supported by all modern browsers.更新(2020 年):所有现代浏览器现在都支持URLSearchParams。

The URLSearchParams utility can be useful for this in combination with window.location.search . URLSearchParams实用程序可以与window.location.search结合使用。 For example:例如:

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

Now foo has been set to bar regardless of whether or not it already existed.现在foo已被设置为bar ,无论它是否已经存在。

However, the above assignment to window.location.search will cause a page load, so if that's not desirable use the History API as follows:但是,上面对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);
}

Now you don't need to write your own regex or logic to handle the possible existence of query strings.现在您无需编写自己的正则表达式或逻辑来处理可能存在的查询字符串。

However, browser support is poor as it's currently experimental and only in use in recent versions of Chrome, Firefox, Safari, iOS Safari, Android Browser, Android Chrome and Opera.然而,浏览器支持很差,因为它目前处于实验阶段,仅在最新版本的 Chrome、Firefox、Safari、iOS Safari、Android 浏览器、Android Chrome 和 Opera 中使用。 Use with a polyfill if you do decide to use it.如果您决定使用polyfill,请与polyfill一起使用。

I have expanded the solution and combined it with another that I found to replace/update/remove the querystring parameters based on the users input and taking the urls anchor into consideration.我扩展了该解决方案并将其与我发现的另一个解决方案相结合,以根据用户输入替换/更新/删除查询字符串参数并考虑 urls 锚点。

Not supplying a value will remove the parameter, supplying one will add/update the parameter.不提供值将删除参数,提供一个将添加/更新参数。 If no URL is supplied, it will be grabbed from window.location如果没有提供 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;
        }
    }
}

Update更新

There was a bug when removing the first parameter in the querystring, I have reworked the regex and test to include a fix.删除查询字符串中的第一个参数时出现错误,我重新编写了正则表达式并进行了测试以包含修复程序。

Second Update第二次更新

As suggested by @JarónBarends - Tweak value check to check against undefined and null to allow setting 0 values正如@JarónBarends 所建议的那样 - 调整值检查以检查 undefined 和 null 以允许设置 0 值

Third Update第三次更新

There was a bug where removing a querystring variable directly before a hashtag would lose the hashtag symbol which has been fixed有一个错误,在主题标签之前直接删除查询字符串变量会丢失已修复的主题标签符号

Fourth Update第四次更新

Thanks @rooby for pointing out a regex optimization in the first RegExp object.感谢@rooby 指出第一个 RegExp 对象中的正则表达式优化。 Set initial regex to ([?&]) due to issue with using (\\?|&) found by @YonatanKarni由于使用@YonatanKarni 发现的 (\\?|&) 问题,将初始正则表达式设置为 ([?&])

Fifth Update第五次更新

Removing declaring hash var in if/else statement删除 if/else 语句中声明的哈希变量

Based on @amateur's answer (and now incorporating the fix from @j_walker_dev comment), but taking into account the comment about hash tags in the url I use the following:基于@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;
  }
}

Edited to fix [?|&] in regex which should of course be [?&] as pointed out in the comments编辑以修复正则表达式中的[?|&] ,这当然应该是[?&]如评论中所指出的

Edit: Alternative version to support removing URL params as well.编辑:支持删除URL 参数的替代版本。 I have used value === undefined as the way to indicate removal.我使用value === undefined作为指示删除的方式。 Could use value === false or even a separate input param as wanted.可以根据需要使用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;
    }
  }
}

See it in action at https://jsfiddle.net/cdt16wex/https://jsfiddle.net/cdt16wex/查看它的实际效果

Here is my library to do that: https://github.com/Mikhus/jsurl这是我的图书馆: https : //github.com/Mikhus/jsurl

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

Thanks to modern javascript, node.js and browsers support, we can get out of 3rd-party library whirlpool (jquery, query-string etc.) and DRY ourselves.多亏了现代 javascript、node.js 和浏览器的支持,我们可以摆脱 3rd-party library whirlpool(jquery、query-string 等)和 DRY。

Here are javascript(node.js) and typescript version for a function that adds or updates query params of given url:以下是用于添加或更新给定 url 的查询参数的函数的 javascript(node.js) 和 typescript 版本:

Javascript 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"}));

Typescript打字稿


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();
};

For React Native对于 React Native

URL is not implemented in React Native. URL未在 React Native 中实现。 So you have to install react-native-url-polyfill beforehand.所以你必须事先安装react-native-url-polyfill

For object params对于对象参数

See the second solution in this answer请参阅此答案中的第二个解决方案

I realize this question is old and has been answered to death, but here's my stab at it.我意识到这个问题已经过时了并且已经得到了死亡的回答,但这是我的尝试。 I'm trying to reinvent the wheel here because I was using the currently accepted answer and the mishandling of URL fragments recently bit me in a project.我试图在这里重新发明轮子,因为我使用的是当前接受的答案,而最近在一个项目中对 URL 片段的错误处理让我感到困惑。

The function is below.功能如下。 It's quite long, but it was made to be as resilient as possible.它很长,但它尽可能地具有弹性。 I would love suggestions for shortening/improving it.我喜欢缩短/改进它的建议。 I put together a small jsFiddle test suite for it (or other similar functions).我为它(或其他类似的功能)组合了一个小的jsFiddle 测试套件 If a function can pass every one of the tests there, I say it's probably good to go.如果一个函数可以通过那里的所有测试,我说它可能很好。

Update: I came across a cool function forusing the DOM to parse URLs , so I incorporated that technique here.更新:我遇到了一个使用 DOM 解析 URL的很酷的函数,所以我在这里合并了该技术。 It makes the function shorter and more reliable.它使功能更短,更可靠。 Props to the author of that function.向该函数的作者提供道具。

/**
 * Add or update a query string parameter. If no URI is given, we use the current
 * window.location.href value for the URI.
 * 
 * Based on the DOM URL parser described here:
 * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/
 *
 * @param   (string)    uri     Optional: The URI to add or update a parameter in
 * @param   (string)    key     The key to add or update
 * @param   (string)    value   The new value to set for key
 *
 * Tested on Chrome 34, Firefox 29, IE 7 and 11
 */
function update_query_string( uri, key, value ) {

    // Use window URL if no query string is provided
    if ( ! uri ) { uri = window.location.href; }

    // Create a dummy element to parse the URI with
    var a = document.createElement( 'a' ), 

        // match the key, optional square brackets, an equals sign or end of string, the optional value
        reg_ex = new RegExp( key + '((?:\\[[^\\]]*\\])?)(=|$)(.*)' ),

        // Setup some additional variables
        qs,
        qs_len,
        key_found = false;

    // Use the JS API to parse the URI 
    a.href = uri;

    // If the URI doesn't have a query string, add it and return
    if ( ! a.search ) {

        a.search = '?' + key + '=' + value;

        return a.href;
    }

    // Split the query string by ampersands
    qs = a.search.replace( /^\?/, '' ).split( /&(?:amp;)?/ );
    qs_len = qs.length; 

    // Loop through each query string part
    while ( qs_len > 0 ) {

        qs_len--;

        // Remove empty elements to prevent double ampersands
        if ( ! qs[qs_len] ) { qs.splice(qs_len, 1); continue; }

        // Check if the current part matches our key
        if ( reg_ex.test( qs[qs_len] ) ) {

            // Replace the current value
            qs[qs_len] = qs[qs_len].replace( reg_ex, key + '$1' ) + '=' + value;

            key_found = true;
        }
    }   

    // If we haven't replaced any occurrences above, add the new parameter and value
    if ( ! key_found ) { qs.push( key + '=' + value ); }

    // Set the new query string
    a.search = '?' + qs.join( '&' );

    return a.href;
}

If it's not set or want to update with a new value you can use:如果未设置或想要使用新值更新,您可以使用:

window.location.search = 'param=value'; // or param=new_value

This is in simple Javascript, by the way.顺便说一下,这是在简单的 Javascript 中。

EDIT编辑

You may want to try using the jquery query-object plugin您可能想尝试使用 jquery查询对象插件

window.location.search = jQuery.query.set("param", 5); window.location.search = jQuery.query.set("param", 5);

window.location.search is read/write. window.location.search 是读/写。

However - modifying the query string will redirect the page you're on and cause a refresh from the server.但是 - 修改查询字符串将重定向您所在的页面并导致服务器刷新。

If what you're attempting to do is maintain client side state (and potentially make it bookmark-able), you'll want to modify the URL hash instead of the query string, which keeps you on the same page (window.location.hash is read/write).如果您试图做的是维护客户端状态(并可能使其成为书签),您将需要修改 URL 哈希而不是查询字符串,这使您保持在同一页面 (window.location.哈希是读/写)。 This is how web sites like twitter.com do this.这就是 twitter.com 等网站的做法。

You'll also want the back button to work, you'll have to bind javascript events to the hash change event, a good plugin for that is http://benalman.com/projects/jquery-hashchange-plugin/您还需要后退按钮工作,您必须将 javascript 事件绑定到哈希更改事件,一个很好的插件是http://benalman.com/projects/jquery-hashchange-plugin/

Here's my approach: The location.params() function (shown below) can be used as a getter or setter.这是我的方法: location.params()函数(如下所示)可以用作 getter 或 setter。 Examples:例子:

Given the URL is http://example.com/?foo=bar&baz#some-hash ,鉴于 URL 是http://example.com/?foo=bar&baz#some-hash

  1. location.params() will return an object with all the query parameters: {foo: 'bar', baz: true} . location.params()将返回一个包含所有查询参数的对象: {foo: 'bar', baz: true}
  2. location.params('foo') will return 'bar' . location.params('foo')将返回'bar'
  3. location.params({foo: undefined, hello: 'world', test: true}) will change the URL to http://example.com/?baz&hello=world&test#some-hash . location.params({foo: undefined, hello: 'world', test: true})会将 URL 更改为http://example.com/?baz&hello=world&test#some-hash

Here is the params() function, which can optionally be assigned to the window.location object.这是params()函数,可以选择将其分配给window.location对象。

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('&');
};

This is my preference, and it covers the cases I can think of.这是我的偏好,它涵盖了我能想到的情况。 Can anyone think of a way to reduce it to a single replace?任何人都可以想出一种方法将其减少为单个替换吗?

function setParam(uri, key, val) {
    return uri
        .replace(RegExp("([?&]"+key+"(?=[=&#]|$)[^#&]*|(?=#|$))"), "&"+key+"="+encodeURIComponent(val))
        .replace(/^([^?&]+)&/, "$1?");
}

It's so simple with URLSearchParams , supported in all modern browsers ( caniuse ).它是这么简单URLSearchParams ,在所有现代浏览器(支持caniuse )。

 let p = new URLSearchParams(); p.set("foo", "bar"); p.set("name", "Jack & Jill?"); console.log("http://example.com/?" + p.toString());

If you want to modify the existing URL, construct the object like this: new URLSearchParams(window.location.search) and assign the string to window.location.search .如果要修改现有 URL,请像这样构造对象: new URLSearchParams(window.location.search)并将字符串分配给window.location.search

I know this is quite old but i want to fires my working version in here.我知道这已经很老了,但我想在这里启动我的工作版本

 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>

NOTE This is a modified version of @elreimundo注意这是@elreimundo的修改版本

You can use the browser's native URL API to do this in a fairly simple way.您可以使用浏览器的本机URL API以相当简单的方式执行此操作。

const url = new URL(location.href);
url.searchParams.set('PARAM_HERE', VALUE_HERE);
history.pushState(null, '', url);

This will preserve everything about the URL and only change or add the one query param.这将保留有关 URL 的所有内容,并且仅更改或添加一个查询参数。 You can also use replaceState instead of pushState if you don't want it to create a new browser history entry.如果您不希望它创建新的浏览器历史记录条目,您也可以使用replaceState代替pushState

My take from here (compatible with "use strict"; does not really use jQuery):从这里开始(与“使用严格”兼容;并没有真正使用 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);
}

Example usage:用法示例:

// 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()));
});

Based on the answer @ellemayo gave, I came up with the following solution that allows for disabling of the hash tag if desired:根据@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;
}

Call it like this:像这样调用它:

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

Results in:结果是:

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

Here is a shorter version that takes care of这是一个较短的版本,可以照顾

  • query with or without a given parameter带或不带给定参数的查询
  • query with multiple parameter values查询多个参数值
  • query containing hash包含哈希的查询

Code:代码:

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);
}

The regex description can be found here .可以在此处找到正则表达式说明。

NOTE : This solution is based on @amateur answer, but with many improvements.注意:此解决方案基于@amateur 答案,但有许多改进。

Code that appends a list of parameters to an existing url using ES6 and jQuery:使用 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;
    }
}

Where listOfParams is like listOfParams 就像

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

Example of Usage:用法示例:

    UrlBuilder.appendParametersToUrl(urlBase, listOfParams);

Fast tests:快速测试:

    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

A different approach without using regular expressions .不使用正则表达式的不同方法。 Supports 'hash' anchors at the end of the url as well as multiple question mark charcters (?).支持 url 末尾的“散列”锚点以及多个问号字符 (?)。 Should be slightly faster than the regular expression approach.应该比正则表达式方法略快。

function setUrlParameter(url, key, value) {
  var parts = url.split("#", 2), anchor = parts.length > 1 ? "#" + parts[1] : '';
  var query = (url = parts[0]).split("?", 2);
  if (query.length === 1) 
    return url + "?" + key + "=" + value + anchor;

  for (var params = query[query.length - 1].split("&"), i = 0; i < params.length; i++)
    if (params[i].toLowerCase().startsWith(key.toLowerCase() + "="))
      return params[i] = key + "=" + value, query[query.length - 1] = params.join("&"), query.join("?") + anchor;

  return url + "&" + key + "=" + value + anchor
}

Use this function to add, remove and modify query string parameter from URL based on jquery使用此函数基于jquery从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];
    }
}

Add new and modify existing parameter to url添加新参数并修改现有参数到 url

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

Remove existing删除现有

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

By using jQuery we can do like below通过使用jQuery我们可以像下面这样

var query_object = $.query_string;
query_object["KEY"] = "VALUE";
var new_url = window.location.pathname + '?'+$.param(query_object)

In variable new_url we will have new query parameters.在变量new_url我们将有新的查询参数。

Reference: http://api.jquery.com/jquery.param/参考: http : //api.jquery.com/jquery.param/

To give an code example for modifying window.location.search as suggested by Gal and tradyblix:给出一个按照 Gal 和 tradyblix 的建议修改window.location.search的代码示例:

var qs = window.location.search || "?";
var param = key + "=" + value; // remember to URI encode your parameters
if (qs.length > 1) {
    // more than just the question mark, so append with ampersand
    qs = qs + "&";
}
qs = qs + param;
window.location.search = qs;

Java script code to find a specific query string and replace its value *用于查找特定查询字符串并替换其值的 Java 脚本代码 *

('input.letter').click(function () {
                //0- prepare values
                var qsTargeted = 'letter=' + this.value; //"letter=A";
                var windowUrl = '';
                var qskey = qsTargeted.split('=')[0];
                var qsvalue = qsTargeted.split('=')[1];
                //1- get row url
                var originalURL = window.location.href;
                //2- get query string part, and url
                if (originalURL.split('?').length > 1) //qs is exists
                {
                    windowUrl = originalURL.split('?')[0];
                    var qs = originalURL.split('?')[1];
                    //3- get list of query strings
                    var qsArray = qs.split('&');
                    var flag = false;
                    //4- try to find query string key
                    for (var i = 0; i < qsArray.length; i++) {
                        if (qsArray[i].split('=').length > 0) {
                            if (qskey == qsArray[i].split('=')[0]) {
                                //exists key
                                qsArray[i] = qskey + '=' + qsvalue;
                                flag = true;
                                break;
                            }
                        }
                    }
                    if (!flag)//   //5- if exists modify,else add
                    {
                        qsArray.push(qsTargeted);
                    }
                    var finalQs = qsArray.join('&');
                    //6- prepare final url
                    window.location = windowUrl + '?' + finalQs;
                }
                else {
                    //6- prepare final url
                    //add query string
                    window.location = originalURL + '?' + qsTargeted;
                }
            })
        });

Here's an alternative method using the inbuilt properties of the anchor HTML element:这是使用锚 HTML 元素的内置属性的替代方法:

  • Handles multi-valued parameters.处理多值参数。
  • No risk of modifying the # fragment, or anything other than the query string itself.没有修改 # 片段或查询字符串本身以外的任何内容的风险。
  • May be a little easier to read?可能更容易阅读? But it is longer.但时间更长。

 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; };

if you want to set multiple parameters at once:如果你想一次设置多个参数:

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

same function as @amateur's与@amateur 的功能相同

if jslint gives you an error add this after the for loop如果 jslint 给你一个错误,在 for 循环之后添加这个

if(params.hasOwnProperty(key))

There are a lot of awkward and unnecessarily complicated answers on this page.这个页面上有很多尴尬和不必要的复杂答案。 The highest rated one, @amateur's, is quite good, although it has a bit of unnecessary fluff in the RegExp.评分最高的@amateur's 相当不错,尽管它在 RegExp 中有些多余。 Here is a slightly more optimal solution with cleaner RegExp and a cleaner replace call:这是一个稍微更优化的解决方案,使用更清洁的 RegExp 和更清洁的replace调用:

function updateQueryStringParamsNoHash(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=[^&]*", "i");
  return re.test(uri)
       ? uri.replace(re, '$1' + key + "=" + value)
       : uri + separator + key + "=" + value
  ;
}

As an added bonus, if uri is not a string, you won't get errors for trying to call match or replace on something that may not implement those methods.作为一个额外的好处,如果uri不是字符串,您将不会因为尝试调用matchreplace某些可能没有实现这些方法的东西而出错。

And if you want to handle the case of a hash (and you've already done a check for properly formatted HTML), you can leverage the existing function instead of writing a new function containing the same logic:如果您想处理散列的情况(并且您已经检查了正确格式化的 HTML),您可以利用现有函数而不是编写包含相同逻辑的新函数:

function updateQueryStringParams(url, key, value) {
    var splitURL = url.split('#');
    var hash = splitURL[1];
    var uri = updateQueryStringParamsNoHash(splitURL[0]);
    return hash == null ? uri : uri + '#' + hash;
}

Or you can make some slight changes to @Adam's otherwise excellent answer:或者您可以对@Adam 的其他出色答案进行一些细微更改:

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=[^&#]*", "i");
  if (re.test(uri)) {
    return uri.replace(re, '$1' + key + "=" + value);
  } else {
    var matchData = uri.match(/^([^#]*)(#.*)?$/);
    var separator = /\?/.test(uri) ? "&" : "?";    
    return matchData[0] + separator + key + "=" + value + (matchData[1] || '');
  }
}

This should serve the purpose:这应该用于以下目的:

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("&");
}   

Here's my slightly different approach to this, written as an excercise这是我对此略有不同的方法,写成练习

function addOrChangeParameters( url, params )
{
  let splitParams = {};
  let splitPath = (/(.*)[?](.*)/).exec(url);
  if ( splitPath && splitPath[2] )
    splitPath[2].split("&").forEach( k => { let d = k.split("="); splitParams[d[0]] = d[1]; } );
  let newParams = Object.assign( splitParams, params );
  let finalParams = Object.keys(newParams).map( (a) => a+"="+newParams[a] ).join("&");
  return splitPath ? (splitPath[1] + "?" + finalParams) : (url + "?" + finalParams);
}

usage:用法:

const url = "http://testing.com/path?empty&value1=test&id=3";

addOrChangeParameters( url, {value1:1, empty:"empty", new:0} )

"http://testing.com/path?empty=empty&value1=1&id=3&new=0"

This answer is just a small tweak of ellemayo's answer.这个答案只是对ellemayo答案的一个小调整。 It will automatically update the URL instead of just returning the updated string.它会自动更新 URL 而不是仅仅返回更新后的字符串。

function _updateQueryString(key, value, url) {
    if (!url) url = window.location.href;

    let updated = ''
    var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"),
        hash;

    if (re.test(url)) {
        if (typeof value !== 'undefined' && value !== null) {
            updated = 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];
            }
            updated = 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];
            }
            updated = url;
        }
        else {
            updated = url;
        }
    }

    window.history.replaceState({ path: updated }, '', updated);
}

Yeah I had an issue where my querystring would overflow and duplicate, but this was due to my own sluggishness.是的,我遇到了一个问题,我的查询字符串会溢出并重复,但这是由于我自己的迟钝。 so I played a bit and worked up some js jquery(actualy sizzle) and C# magick.所以我玩了一点,研究了一些 js jquery(实际上是 sizzle)和 C# magick。

So i just realized that after the server has done with the passed values, the values doesn't matter anymore, there is no reuse, if the client wanted to do the same thing evidently it will always be a new request, even if its the same parameters being passed.所以我刚刚意识到,在服务器完成传递的值之后,这些值不再重要,没有重用,如果客户端想要做同样的事情,显然它总是一个新的请求,即使它是传递相同的参数。 And thats all clientside, so some caching/cookies etc could be cool in that regards.这就是所有客户端,所以一些缓存/cookie 等在这方面可能很酷。

JS: JS:

$(document).ready(function () {
            $('#ser').click(function () {
                SerializeIT();
            });
            function SerializeIT() {
                var baseUrl = "";
                baseUrl = getBaseUrlFromBrowserUrl(window.location.toString());
                var myQueryString = "";
                funkyMethodChangingStuff(); //whatever else before serializing and creating the querystring
                myQueryString = $('#fr2').serialize();
                window.location.replace(baseUrl + "?" + myQueryString);
            }
            function getBaseUrlFromBrowserUrl(szurl) {
                return szurl.split("?")[0];
            } 
            function funkyMethodChangingStuff(){
               //do stuff to whatever is in fr2
            }
        });

HTML: HTML:

<div id="fr2">
   <input type="text" name="qURL" value="http://somewhere.com" />
   <input type="text" name="qSPart" value="someSearchPattern" />
</div>
<button id="ser">Serialize! and go play with the server.</button>

C#: C#:

    using System.Web;
    using System.Text;
    using System.Collections.Specialized;

    public partial class SomeCoolWebApp : System.Web.UI.Page
    {
        string weburl = string.Empty;
        string partName = string.Empty;

        protected void Page_Load(object sender, EventArgs e)
        {
            string loadurl = HttpContext.Current.Request.RawUrl;
            string querySZ = null;
            int isQuery = loadurl.IndexOf('?');
            if (isQuery == -1) { 
                //If There Was no Query
            }
            else if (isQuery >= 1) {
                querySZ = (isQuery < loadurl.Length - 1) ? loadurl.Substring(isQuery + 1) : string.Empty;
                string[] getSingleQuery = querySZ.Split('?');
                querySZ = getSingleQuery[0];

                NameValueCollection qs = null;
                qs = HttpUtility.ParseQueryString(querySZ);

                weburl = qs["qURL"];
                partName = qs["qSPart"];
                //call some great method thisPageRocks(weburl,partName); or whatever.
          }
      }
  }

Okay criticism is welcome (this was a nightly concoction so feel free to note adjustments).好的,欢迎批评(这是每晚的混合物,所以请随时注意调整)。 If this helped at all, thumb it up, Happy Coding.如果这有帮助,请竖起大拇指,Happy Coding。

No duplicates, each request as unique as you modified it, and due to how this is structured,easy to add more queries dynamicaly from wthin the dom.没有重复,每个请求在您修改它时都是独一无二的,并且由于它的结构,很容易从 dom 中动态添加更多查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM