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


364

使用javascript,如何将查询字符串参数添加到url(如果不存在)或如果存在,则更新当前值?我正在使用jquery进行客户端开发。


1
在我的职业生涯中,我似乎已经用JavaScript编写了“ parseQueryString”函数约100次。不难 关键点,String#split采用第二个参数进行最大分割。jQuery map也会有所帮助。
jpsimons 2011年

这个所谓后也有很多的解决方案stackoverflow.com/questions/1090948/...
迪利普·拉库玛

1
有些人认为这个问题的意思是“如何更改地址栏中的URL”,而其他人则表示“如何更改任何URL变量”
PandaWood '16

Answers:


468

我编写了以下函数来实现我想要实现的功能:

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

36
当URI中存在哈希时,此答案不起作用-查询字符串必须放在哈希之前,否则它们不会发送到服务器。jsfiddle.net/4yXzR
Greg

20
[?|&]应该是[?&]
soju 2012年

8
通过var在分隔符声明之前添加,将分隔符变量作用域限制为局部函数 。
Andrea Salicetti 2012年

3
我认为,您应该value = encodeURIComponent(value);在第一行中添加,否则不能正确地换行。
Felix


189

我已经扩展了该解决方案,并将其与我发现的另一个解决方案结合在一起,可以根据用户输入并考虑url锚点来替换/更新/删除querystring参数。

不提供值将删除该参数,提供一个将添加/更新该参数。如果没有提供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所建议的那样-调整值检查以检查未定义和null以允许设置0值

第三次更新

有一个错误,即在主题标签将丢失已经修复的主题标签符号之前直接删除查询字符串变量

第四次更新

感谢@rooby指出第一个RegExp对象中的正则表达式优化。由于使用@YonatanKarni发现的(\?|&)问题,将初始正则表达式设置为([?&])

第五次更新

在if / else语句中删除声明hash var


5
只是检查的“感实性” value将导致此从查询字符串删除变量时,其值设置为0。所以不是if (value) {}你应该使用if (typeOf value !== 'undefined' && value !== null) {}
搅得Barends

1
在RegExp中,[[?|&])应该确实是([?&])
rooby 2014年

有趣的是从原始解决方案中继承来的内容-也可以使用(\?|&)
ellemayo 2014年

1
在Chrome版本31.0.1650.63中,在创建正则表达式时遇到“无效的常规异常/无效的组”异常,解决方法是将开头返回为“([?&])”
Yonatan Karni 2014年

1
除了我是OCD之外,这并不重要,但是变量hash被声明了两次;)
wlingke 2014年

117

URLSearchParams实用程序可以与组合是这个有用的window.location.search。例如:

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

现在foo已设置为bar,无论它是否已经存在。

但是,上述对的分配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);
}

现在,您无需编写自己的正则表达式或逻辑来处理查询字符串的可能存在。

但是,浏览器支持很差,因为它目前处于试验阶段,仅在最新版本的Chrome,Firefox,Safari,iOS Safari,Android浏览器,Android Chrome和Opera中使用。如果您决定使用它,请与polyfill一起使用。

更新:自从我最初回答以来,浏览器支持得到了改善。


波利填充,不是很好, Unable to set property '__URLSearchParams__:0.8503766759030615' of undefined or null reference 在ie11上您会收到该错误。如果它不能用作后备广告,则不是pollyfill。
Val

6
2019年更新:现在,除了IE和某些小型移动浏览器之外,大多数浏览器都对浏览器提供了很好的支持。的ungap新pollyfill轻松地涵盖了:github.com/ungap/url-search-params
Flion

完美的答案,但是当URL中包含#号时,它就无法处理用例。简单地将哈希值附加到末尾即可达到目的newRelativePathQueryvar newRelativePathQuery = window.location.pathname + '?' + searchParams.toString() + window.location.hash;
kudlohlavec

43

基于@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;
  }
}

编辑以修复[?|&]正则表达式,这当然应该[?&]如注释中所指出

编辑:替代版本也支持删除URL参数。我已经用作value === undefined指示删除的方式。可以根据需要使用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');
    } 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;
  }
  }  
}

https://jsfiddle.net/bp3tmuxh/1/上查看运行中的情况


2
干净得多。对于可以使用“?”的有角度的ui路由器用户,请参考 在哈希中。将var separator行移动到返回上方的右边可修复“ / app#/ cool?fun = true”错误。即使没有真正的查询字符串参数,也将选择“&”作为分隔符。只有客户的。
j_walker_dev 2015年

3
正如在其他答案的评论中指出的那样,[?|&]应该是公正的[?&](否则将匹配|)。
邦杰

1
是的,"([?|&])"不好。请将此问题修复为var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");(以其他方式进行扩展)!
YakovL

好的,抱歉,var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");它不起作用,第二个则可以
YakovL

似乎此版本不支持通过省略值来删除查询字符串参数。我对吗?
jkupczak


11

window.location.search是读/写的。

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

如果您要尝试维护客户端状态(并可能使其具有书签功能),则需要修改URL哈希而不是查询字符串,这样可以使您位于同一页面(window.location)。哈希是可读写的)。像twitter.com这样的网站就是这样做的。

您还希望后退按钮能够正常工作,必须将javascript事件绑定到哈希更改事件,对此的一个很好的插件是http://benalman.com/projects/jquery-hashchange-plugin/


4
Twitter不再修改哈希!哈希值已死,欢迎使用History API
阿尔巴·门德斯

距离死亡还很远。我认为您生活在一个神奇的梦境中,与旧版浏览器的兼容性无关紧要。对于您来说可能是这种情况,但对于我们其他人(实际上是我们大多数人)而言,情况肯定并非如此。也许死亡更合适……
AaronHS 2015年

1
一年后,它似乎是唯一不支持它的半新浏览器是IE 9
Douglas.Sesar,2016年

11

如果未设置或要使用新值进行更新,则可以使用:

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

顺便说一下,这是用简单的Java语言编写的。

编辑

您可能想尝试使用jquery 查询对象插件

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


1
但这不会在url上保留任何其他查询字符串参数。
业余时间

您是对的,我道歉..作为更新,我在回答中添加了另一个选项:)
tradyblix

这不起作用,因为它不会重置值。“添加或更新”
Paolo Falomo

11

我知道这个问题很旧,已经被回答死了,但这是我的问题。我试图在这里重新发明轮子,因为我使用的是当前接受的答案,而URL片段的处理不当最近使我陷入了一个项目。

该功能如下。它很长,但是要使其具有尽可能的弹性。我希望缩短或改善它的建议。我为此组装了一个小型jsFiddle测试套件(或其他类似功能)。如果一个函数可以通过那里的每个测试,那么我说这样做可能很好。

更新:我遇到了一个很酷的函数,函数使用DOM解析URL,因此我在此处合并了该技术。它使功能更短,更可靠。向该函数的作者提出建议。

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

2
这看起来确实不错,可靠的测试用例+使用DOM作为URL解析器。我确实发现了两种情况:example.com/? param = val& => example.com/?param=val&&new=key --double&和example.com/team => example.com/team?new=key应该是: team /?new = key将/ team?new = key重定向到/ team /,查询将丢失。
Timar Ivo Batis

1
感谢失败的测试用例。我更新了小提琴。那第一个很艰难。关于如何修复该功能的任何想法?第二个应该没有问题,并且已经包含在测试套件中。也许我不明白你的意思。随意拨弄小提琴来演示您所看到的。
Dominic P

我添加了一些我遇到的测试用例和解决方法。我试图尽可能多地使用DOM。首先,我需要它也可以用于同一域中的相对链接。jsfiddle.net/Timar/7sjrhbm3
Timar Ivo Batis '18

1
@braed我喜欢这种方法,因为它将繁琐的工作留给浏览器。从这里的许多答案中可以看出,这个问题并不像看起来那样简单。解决方案需要解决很多角落问题。当您利用DOM时,其中大多数都是免费的。
Dominic P

1
@braed一定要看看我在答案中链接的测试套件。这里很多不依赖DOM的解决方案都失败了,因为它们不能解决列出的所有极端情况。至于阅读,查看node.js 的URL模块可能会很有帮助。它并不直接相关,但可以让您了解URL字符串所涉及的一些复杂性。
Dominic P

9

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

鉴于网址为http://example.com/?foo=bar&baz#some-hash

  1. location.params() 将返回具有所有查询参数的对象: {foo: 'bar', baz: true}
  2. location.params('foo') 将返回 'bar'
  3. location.params({foo: undefined, hello: 'world', test: true})会将网址更改为http://example.com/?baz&hello=world&test#some-hash

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


5

我知道这已经很老了,但我想在这里解雇我的工作版本

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的修改版本



2

从这里获得的经验(与“ use strict”兼容;并不真正使用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()));
});

2

根据@ellemayo给出的答案,我提出了以下解决方案,该解决方案允许在需要时禁用hash标签:

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

风格化的bble测:typeof value !== 'undefined' && value !== null更明确,但value != null含义相同,更简洁。
eppsilon

2

这是一个简短的版本,照顾

  • 有或没有给定参数的查询
  • 查询多个参数值
  • 包含哈希的查询

码:

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答案,但有许多改进。


2

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

1

不使用正则表达式的另一种方法。支持url末尾的“哈希”锚点以及多个问号字符(?)。应该比正则表达式方法快一点。

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
}

1

使用此功能可基于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];
    }
}

添加新的并修改现有参数到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

1

通过使用jQuery我们可以做到如下

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

在变量中,new_url我们将有新的查询参数。

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


0

给出window.location.searchGal和tradyblix建议的修改代码示例:

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;

0

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

0

是的,我有一个问题,我的查询字符串会溢出并重复,但这是由于我自己的呆滞。所以我玩了一点,做了一些js jquery(准确地发出嘶嘶声)和C#magick。

所以我刚刚意识到,服务器处理完传递的值后,这些值不再重要,不再有重用,如果客户端显然想做同样的事情,它将始终是一个新请求,即使它是传递相同的参数。多数民众赞成在所有客户端,因此一些缓存/ Cookie等在这方面可能很酷。

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:

<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#:

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

好的批评是值得欢迎的(这是每晚的调酒,请随时注意调整)。如果这完全有帮助,请竖起大拇指,快乐编码。

没有重复,每个请求都像您修改的那样具有唯一性,并且由于其结构如何,很容易从dom中动态添加更多查询。


0

这是使用锚点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;
	};


0

如果要一次设置多个参数:

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

与@amateur的功能相同

如果jslint给您一个错误,请在for循环后添加

if(params.hasOwnProperty(key))

不处理散列,或未为参数分配value(http://abc.def/?a&b&c)的参数。
亚当·莱格特

0

此页面上有很多笨拙且不必要的复杂答案。评分最高的@amateur的表现不错,尽管RegExp中有一些不必要的绒毛。这是使用更清洁的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
  ;
}

另外,如果uri不是字符串,则不会因尝试调用matchreplace执行可能无法实现这些方法的错误而出错。

而且,如果您要处理哈希的情况(并且已经对格式正确的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;
}

或者,您可以对@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] || '');
  }
}

2
这是最后一个函数中缺少的括号:var matchData = uri.match(/^([^#]*)(#.*)?$/
Jammer

separator未在中定义updateQueryStringParamsNoHash。在中updateQueryStringParameter,如果您要替换的参数未分配值(例如http://abc.def/?a&b&c),则一切中断。
亚当·莱格特

0

这应该达到以下目的:

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("&");
}   
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.