使用JavaScript向URL添加参数


276

在使用AJAX调用的Web应用程序中,我需要提交一个请求,但要在URL的末尾添加一个参数,例如:

原始网址:

http://server/myapp.php?id = 10

结果网址:

http://server/myapp.php?id = 10 &enabled = true

寻找一种JavaScript函数,该函数解析URL并查看每个参数,然后添加新参数或更新值(如果已经存在)。


您是否搜索过javascript网址解析器?您可以自己制作,分割每个&字符,但仅使用现有代码可能会更容易。
csl

1
我曾经有过类似的情况,我发现Peter Bromberg的这篇文章很有帮助:
Cerebrus

2
window.history.pushState('page2','Title',document.location +'/ page2.php'); 将在不加载页面的情况下完成您的工作
Rutunj sheladiya 2015年

1
这个问题在这里有更好的答案stackoverflow.com/questions/6953944/…–
rkb

令人难以置信的是,这不是这种可口的语言的母语,因为JS是....
bohr

Answers:


191

您需要调整的基本实现如下所示:

function insertParam(key, value) {
    key = encodeURIComponent(key);
    value = encodeURIComponent(value);

    // kvp looks like ['key1=value1', 'key2=value2', ...]
    var kvp = document.location.search.substr(1).split('&');
    let i=0;

    for(; i<kvp.length; i++){
        if (kvp[i].startsWith(key + '=')) {
            let pair = kvp[i].split('=');
            pair[1] = value;
            kvp[i] = pair.join('=');
            break;
        }
    }

    if(i >= kvp.length){
        kvp[kvp.length] = [key,value].join('=');
    }

    // can return this or...
    let params = kvp.join('&');

    // reload page with new params
    document.location.search = params;
}

这大约是正则表达式或基于搜索的解决方案速度的两倍,但这完全取决于查询字符串的长度和任何匹配项的索引


我为完成测试而基准的慢速正则表达式方法(慢了大约150%)

function insertParam2(key,value)
{
    key = encodeURIComponent(key); value = encodeURIComponent(value);

    var s = document.location.search;
    var kvp = key+"="+value;

    var r = new RegExp("(&|\\?)"+key+"=[^\&]*");

    s = s.replace(r,"$1"+kvp);

    if(!RegExp.$1) {s += (s.length>0 ? '&' : '?') + kvp;};

    //again, do what you will here
    document.location.search = s;
}

2
再次感谢。有关方法的基本比较,请参见lessanvaezi.com/wp-content/uploads/2009/01/test.html
Lessan Vaezi 09年

16
使用escape()来转义URL参数是错误的。对于其中带有“ +”的值,它会中断。您应该改为使用encodeURIComponent。完整讨论:xkr.us/articles/javascript/encode-compare
Antonin Hildebrand

4
我正在调用此函数,并且页面在无限循环中重新加载。请帮忙!
SUMIT

6
当网址中没有参数时,您会得到一个?&param = value
Roy Toledo

9
您不应该使用encodeURIComponent而不是encodeURI吗?否则=&您的名称或值之类的任何字符(如)都会损坏URI。
Adrian Pronk

271

您可以使用以下之一:

例:

var url = new URL("http://foo.bar/?x=1&y=2");

// If your expected result is "http://foo.bar/?x=1&y=2&x=42"
url.searchParams.append('x', 42);

// If your expected result is "http://foo.bar/?x=42&y=2"
url.searchParams.set('x', 42);

2
我想添加一个不带值的查询参数,例如,添加XMLhttp://foo.bar/?x=1&y=2,使最终结果为http://foo.bar/?x=1&y=2&XML。这可能吗?我想url.searchParams.set('XML');url.searchParams.set('XML', null);url.searchParams.set('XML', undefined);-但没有工作过的Chrome 63
Abdull

2
谢谢!遗憾的是,iOS尚不支持该功能。developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
汉字

27
糟糕的IE不支持它。
spedy

3
iOS现在确实支持URLSearchParams(自
@kanji

8
好消息@MJeffryes!IE和Netscape仍不支持。
Vianney Bajart '18

64

谢谢大家的贡献。我使用了annakata代码,并进行了修改,以包括网址中根本没有查询字符串的情况。希望这会有所帮助。

function insertParam(key, value) {
        key = escape(key); value = escape(value);

        var kvp = document.location.search.substr(1).split('&');
        if (kvp == '') {
            document.location.search = '?' + key + '=' + value;
        }
        else {

            var i = kvp.length; var x; while (i--) {
                x = kvp[i].split('=');

                if (x[0] == key) {
                    x[1] = value;
                    kvp[i] = x.join('=');
                    break;
                }
            }

            if (i < 0) { kvp[kvp.length] = [key, value].join('='); }

            //this will reload the page, it's likely better to store this until finished
            document.location.search = kvp.join('&');
        }
    }

3
这将是更好的变化从escape(key)escape(value)encodeURIComponent功能。
kolobok,2015年

5
这应该检查if (kvp.length==1 && kvp[0]="")吗?
Charles L.

@CharlesL。更好的是if (document.location.search)
Lyubimov Roman

58

这是非常简单的解决方案。它不控制参数的存在,并且不更改现有值。它将参数添加到末尾,因此您可以在后端代码中获取最新值。

function addParameterToURL(param){
    _url = location.href;
    _url += (_url.split('?')[1] ? '&':'?') + param;
    return _url;
}

6
您还应该在网址中输入“#”。这是一些代码url = (url.indexOf("?") != -1 ? url.split("?")[0]+"?"+part+"&"+url.split("?")[1] : (url.indexOf("#") != -1 ? url.split("#")[0]+"?"+part+"#"+ url.split("#")[1] : url+'?'+part));
漏洞

2
@kanzure这东西看起来很邪恶,但这正是我想要的。谢谢。
乍得冯瑙

为什么拆分URL以检查是否存在单个字符?也不要忘记编码...更像是function appendQs(url, key, value) { return url + (url.indexOf('?') >= 0 ? "&" : '?') + encodeURIComponent(key) + "=" + encodeURIComponent(value); };
drzaus

1
修理它。该功能不检查参数是否已经提供。我测试了一下https://localhost/preview/inventory.html?sortci=priceASC&sortci=priceASC&sortci=stitle
杰伊

@Jay,为什么需要修复?检查您的假设。重复查询字符串参数是合法的,与重复表单字段相同。这是在HTML中实现复选框列表的方式。如果使用method = get形式,则这些列表将通过查询字符串传递。
斯蒂芬

34

这是一个大大简化的版本,在易读性和较少的代码行数(而不是微优化的性能)之间进行了权衡(实际上,我们谈论的是几毫秒的差异,由于这种性质(在当前文档的位置上进行操作) ),则很可能会在页面上运行一次)。

/**
* Add a URL parameter (or changing it if it already exists)
* @param {search} string  this is typically document.location.search
* @param {key}    string  the key to set
* @param {val}    string  value 
*/
var addUrlParam = function(search, key, val){
  var newParam = key + '=' + val,
      params = '?' + newParam;

  // If the "search" string exists, then build params from it
  if (search) {
    // Try to replace an existance instance
    params = search.replace(new RegExp('([?&])' + key + '[^&]*'), '$1' + newParam);

    // If nothing was replaced, then add the new param to the end
    if (params === search) {
      params += '&' + newParam;
    }
  }

  return params;
};

然后,您将这样使用:

document.location.pathname + addUrlParam(document.location.search, 'foo', 'bar');

1
1,我喜欢你如何可以指定比document.location.search以外的东西
Muhd

1
+1很棒,我同意在这种情况下,易读性比微优化更重要,我很高兴看到有人采用了这种方法。@Muhd也许当您编写该注释时,这是JS引擎中的错误,但我只是在这种情况下测试了“ $ 1”,并且效果很好。
JMTyler 2014年

非常感谢您提供的解决方案,尽管如果我要替换一个值并且那里已经有一个参数,我也会感到困惑。取而代之的是&,它会写$ 1
Codebryo,2015年

2
Garrett:您能解决您的问题,以便正确替换现有参数吗?这只是一个替代的事情[\?&]([\?&])在正则表达式(我只是编辑它自己,但我不知道如果社会政策允许的答案修复bug)。
opyh 2015年

这不适用于像“ domain.tld ” 这样的网址,其添加“&”而不是“?”
user706420 '16

20

/**
* Add a URL parameter 
* @param {string} url 
* @param {string} param the key to set
* @param {string} value 
*/
var addParam = function(url, param, value) {
   param = encodeURIComponent(param);
   var a = document.createElement('a');
   param += (value ? "=" + encodeURIComponent(value) : ""); 
   a.href = url;
   a.search += (a.search ? "&" : "") + param;
   return a.href;
}

/**
* Add a URL parameter (or modify if already exists)
* @param {string} url 
* @param {string} param the key to set
* @param {string} value 
*/
var addOrReplaceParam = function(url, param, value) {
   param = encodeURIComponent(param);
   var r = "([&?]|&amp;)" + param + "\\b(?:=(?:[^&#]*))*";
   var a = document.createElement('a');
   var regex = new RegExp(r);
   var str = param + (value ? "=" + encodeURIComponent(value) : ""); 
   a.href = url;
   var q = a.search.replace(regex, "$1"+str);
   if (q === a.search) {
      a.search += (a.search ? "&" : "") + str;
   } else {
      a.search = q;
   }
   return a.href;
}

url = "http://www.example.com#hashme";
newurl = addParam(url, "ciao", "1");
alert(newurl);

并且请注意,在将参数附加到查询字符串之前,应先对其进行编码。

http://jsfiddle.net/48z7z4kx/


内存泄漏小-您需要在返回之前删除添加到文档中的锚元素。

@freedev,不,我不确定。;)我很难找到权威来源,但是证据表明您是正确的。由于创建的元素永远不会附加到DOM,因此一旦变量超出范围,就应该将其清除。当涉及到副作用时,DOM API的设计不是特别好,所以我过于谨慎。

此解决方案在没有路径和重新排序参数的URL上添加斜杠,这是不必要的,而且可能是不希望的更改。它还会附加而不是替换没有值的现有参数(例如http://abc.def/?a&b&b)。
亚当·莱格特

@AdamLeggett感谢您指出当请求参数没有值时发生的错误,我已经解决了我的问题。如果您说对了,剩下的奇怪行为是由HTML锚对象生成的,该对象通常是标准的浏览器组件。我建议仔细检查,因为浏览器不太可能会添加不必要或不良行为。
freedev

1
addParam函数的目的确实是多次添加一个参数,也许您应该知道即使多次使用相同的值也可以传递相同的参数。stackoverflow.com/questions/24059773/...
freedev

19

我有一个“类”来做到这一点,这里是:

function QS(){
    this.qs = {};
    var s = location.search.replace( /^\?|#.*$/g, '' );
    if( s ) {
        var qsParts = s.split('&');
        var i, nv;
        for (i = 0; i < qsParts.length; i++) {
            nv = qsParts[i].split('=');
            this.qs[nv[0]] = nv[1];
        }
    }
}

QS.prototype.add = function( name, value ) {
    if( arguments.length == 1 && arguments[0].constructor == Object ) {
        this.addMany( arguments[0] );
        return;
    }
    this.qs[name] = value;
}

QS.prototype.addMany = function( newValues ) {
    for( nv in newValues ) {
        this.qs[nv] = newValues[nv];
    }
}

QS.prototype.remove = function( name ) {
    if( arguments.length == 1 && arguments[0].constructor == Array ) {
        this.removeMany( arguments[0] );
        return;
    }
    delete this.qs[name];
}

QS.prototype.removeMany = function( deleteNames ) {
    var i;
    for( i = 0; i < deleteNames.length; i++ ) {
        delete this.qs[deleteNames[i]];
    }
}

QS.prototype.getQueryString = function() {
    var nv, q = [];
    for( nv in this.qs ) {
        q[q.length] = nv+'='+this.qs[nv];
    }
    return q.join( '&' );
}

QS.prototype.toString = QS.prototype.getQueryString;

//examples
//instantiation
var qs = new QS;
alert( qs );

//add a sinle name/value
qs.add( 'new', 'true' );
alert( qs );

//add multiple key/values
qs.add( { x: 'X', y: 'Y' } );
alert( qs );

//remove single key
qs.remove( 'new' )
alert( qs );

//remove multiple keys
qs.remove( ['x', 'bogus'] )
alert( qs );

我已经重写了toString方法,因此无需调用QS :: getQueryString,您可以使用QS :: toString,或者像我在示例中所做的那样,仅依赖于被强制转换为字符串的对象。


19
const urlParams = new URLSearchParams(window.location.search);

urlParams.set('order', 'date');

window.location.search = urlParams;

.set第一个参数是关键,第二个是值。


1
喜欢它的简单性,它使用本机浏览器方法
Juan Solano,

2
这是正确的答案,应予以最高评价。这个新的API是明确的URL处理
安东尼

8

如果您有一个要用参数修饰的带有url的字符串,则可以尝试以下操作:

urlstring += ( urlstring.match( /[\?]/g ) ? '&' : '?' ) + 'param=value';

这意味着什么?将是参数的前缀,但是如果已经有在中urlstring,将用作前缀。

encodeURI( paramvariable )如果您没有对参数进行硬编码,我也建议您这样做,但是它位于paramvariable;中;或者其中有有趣的人物。

有关功能的用法,请参见javascript URL编码encodeURI


7

这是添加查询参数的简单方法:

const query = new URLSearchParams(window.location.search);
query.append("enabled", "true");

而且这里还有更多

请注意支持规格


4
似乎Internet Explorer的任何版本均不支持此功能
MAXE

移动的理想选择。当我的移动设备上显示Internet Explorer时,我将其丢弃。:-)
stillatmylinux

@MAXE你说的对IE / EDGE不太支持。
T04435 '17

6

查看https://github.com/derek-watson/jsUri

URI和javascript中的查询字符串操作。

该项目包含了Steven Levithan出色的parseUri正则表达式库。您可以安全地解析各种形状和大小的URL,但是这些URL无效或令人生厌。


404-在此服务器上找不到请求的URL / p / jsuri /。我们知道的就这些。
Aligma 2014年

1
看起来已经被移动了。我已经更新了网址。祝你好运!
查理·梁元

请在答案中包括相关详细信息,而不仅仅是链接。
jhpratt GOFUNDME授权

6

有时,我们?在URL的结尾看到了一些解决方案,它们生成的结果为file.php?&foo=bar。我想出了自己的解决方案,可以按我的意愿完美地工作!

location.origin + location.pathname + location.search + (location.search=='' ? '?' : '&') + 'lang=ar'

注意:location.origin在IE中不起作用,这是其修复方法


6

以下功能将帮助您向URL添加,更新和删除参数。

// example1and

var myURL = '/search';

myURL = updateUrl(myURL,'location','california');
console.log('added location...' + myURL);
//added location.../search?location=california

myURL = updateUrl(myURL,'location','new york');
console.log('updated location...' + myURL);
//updated location.../search?location=new%20york

myURL = updateUrl(myURL,'location');
console.log('removed location...' + myURL);
//removed location.../search

// example2

var myURL = '/search?category=mobile';

myURL = updateUrl(myURL,'location','california');
console.log('added location...' + myURL);
//added location.../search?category=mobile&location=california

myURL = updateUrl(myURL,'location','new york');
console.log('updated location...' + myURL);
//updated location.../search?category=mobile&location=new%20york

myURL = updateUrl(myURL,'location');
console.log('removed location...' + myURL);
//removed location.../search?category=mobile

// example3

var myURL = '/search?location=texas';

myURL = updateUrl(myURL,'location','california');
console.log('added location...' + myURL);
//added location.../search?location=california

myURL = updateUrl(myURL,'location','new york');
console.log('updated location...' + myURL);
//updated location.../search?location=new%20york

myURL = updateUrl(myURL,'location');
console.log('removed location...' + myURL);
//removed location.../search

// example4

var myURL = '/search?category=mobile&location=texas';

myURL = updateUrl(myURL,'location','california');
console.log('added location...' + myURL);
//added location.../search?category=mobile&location=california

myURL = updateUrl(myURL,'location','new york');
console.log('updated location...' + myURL);
//updated location.../search?category=mobile&location=new%20york

myURL = updateUrl(myURL,'location');
console.log('removed location...' + myURL);
//removed location.../search?category=mobile

// example5

var myURL = 'https://example.com/search?location=texas#fragment';

myURL = updateUrl(myURL,'location','california');
console.log('added location...' + myURL);
//added location.../search?location=california#fragment

myURL = updateUrl(myURL,'location','new york');
console.log('updated location...' + myURL);
//updated location.../search?location=new%20york#fragment

myURL = updateUrl(myURL,'location');
console.log('removed location...' + myURL);
//removed location.../search#fragment

这是功能。

function updateUrl(url,key,value){
      if(value!==undefined){
        value = encodeURI(value);
      }
      var hashIndex = url.indexOf("#")|0;
      if (hashIndex === -1) hashIndex = url.length|0;
      var urls = url.substring(0, hashIndex).split('?');
      var baseUrl = urls[0];
      var parameters = '';
      var outPara = {};
      if(urls.length>1){
          parameters = urls[1];
      }
      if(parameters!==''){
        parameters = parameters.split('&');
        for(k in parameters){
          var keyVal = parameters[k];
          keyVal = keyVal.split('=');
          var ekey = keyVal[0];
          var evalue = '';
          if(keyVal.length>1){
              evalue = keyVal[1];
          }
          outPara[ekey] = evalue;
        }
      }

      if(value!==undefined){
        outPara[key] = value;
      }else{
        delete outPara[key];
      }
      parameters = [];
      for(var k in outPara){
        parameters.push(k + '=' + outPara[k]);
      }

      var finalUrl = baseUrl;

      if(parameters.length>0){
        finalUrl += '?' + parameters.join('&'); 
      }

      return finalUrl + url.substring(hashIndex); 
  }

5

这是我自己的尝试,但是我将使用annakata的答案,因为它看起来更干净:

function AddUrlParameter(sourceUrl, parameterName, parameterValue, replaceDuplicates)
{
    if ((sourceUrl == null) || (sourceUrl.length == 0)) sourceUrl = document.location.href;
    var urlParts = sourceUrl.split("?");
    var newQueryString = "";
    if (urlParts.length > 1)
    {
        var parameters = urlParts[1].split("&");
        for (var i=0; (i < parameters.length); i++)
        {
            var parameterParts = parameters[i].split("=");
            if (!(replaceDuplicates && parameterParts[0] == parameterName))
            {
                if (newQueryString == "")
                    newQueryString = "?";
                else
                    newQueryString += "&";
                newQueryString += parameterParts[0] + "=" + parameterParts[1];
            }
        }
    }
    if (newQueryString == "")
        newQueryString = "?";
    else
        newQueryString += "&";
    newQueryString += parameterName + "=" + parameterValue;

    return urlParts[0] + newQueryString;
}

另外,我在stackoverflow的另一篇文章中找到了这个jQuery插件,如果您需要更大的灵活性,可以使用它:http : //plugins.jquery.com/project/query-object

我认为代码会(尚未测试):

return $.query.parse(sourceUrl).set(parameterName, parameterValue).toString();

感谢您共享代码,Lessan。我一直在使用它,效果很好!我已经上传了自己版本的要点,对其进行了编辑,使其更加简洁,并通过了JSHint验证。gist.github.com/jonathanconway/02a183920506acd9890a
Jonathan

3

添加到@Vianney的答案https://stackoverflow.com/a/44160941/6609678

我们可以按如下所示在节点中导入内置URL模块

const { URL } = require('url');

例:

Terminal $ node
> const { URL } = require('url');
undefined
> let url = new URL('', 'http://localhost:1989/v3/orders');
undefined
> url.href
'http://localhost:1989/v3/orders'
> let fetchAll=true, timePeriod = 30, b2b=false;
undefined
> url.href
'http://localhost:1989/v3/orders'
>  url.searchParams.append('fetchAll', fetchAll);
undefined
>  url.searchParams.append('timePeriod', timePeriod);
undefined
>  url.searchParams.append('b2b', b2b);
undefined
> url.href
'http://localhost:1989/v3/orders?fetchAll=true&timePeriod=30&b2b=false'
> url.toString()
'http://localhost:1989/v3/orders?fetchAll=true&timePeriod=30&b2b=false'

有用的链接:

https://developer.mozilla.org/zh-CN/docs/Web/API/URL https://developer.mozilla.org/en/docs/Web/API/URLSearchParams


3

试试这个。

// uses the URL class
function setParam(key, value) {
            let url = new URL(window.document.location);
            let params = new URLSearchParams(url.search.slice(1));

            if (params.has(key)) {
                params.set(key, value);
            }else {
                params.append(key, value);
            }
        }

url.searchParams是该URL对象的预初始化参数列表。
amphetamachine

2

我喜欢Mehmet FatihYıldız的回答,即使他没有回答整个问题。

在与他的答案相同的行中,我使用以下代码:

“它不会控制参数的存在,并且不会更改现有值。它将参数添加到末尾”

  /** add a parameter at the end of the URL. Manage '?'/'&', but not the existing parameters.
   *  does escape the value (but not the key)
   */
  function addParameterToURL(_url,_key,_value){
      var param = _key+'='+escape(_value);

      var sep = '&';
      if (_url.indexOf('?') < 0) {
        sep = '?';
      } else {
        var lastChar=_url.slice(-1);
        if (lastChar == '&') sep='';
        if (lastChar == '?') sep='';
      }
      _url += sep + param;

      return _url;
  }

和测试人员:

  /*
  function addParameterToURL_TESTER_sub(_url,key,value){
    //log(_url);
    log(addParameterToURL(_url,key,value));
  }

  function addParameterToURL_TESTER(){
    log('-------------------');
    var _url ='www.google.com';
    addParameterToURL_TESTER_sub(_url,'key','value');
    addParameterToURL_TESTER_sub(_url,'key','Text Value');
    _url ='www.google.com?';
    addParameterToURL_TESTER_sub(_url,'key','value');
    _url ='www.google.com?A=B';
    addParameterToURL_TESTER_sub(_url,'key','value');
    _url ='www.google.com?A=B&';
    addParameterToURL_TESTER_sub(_url,'key','value');
    _url ='www.google.com?A=1&B=2';
    addParameterToURL_TESTER_sub(_url,'key','value');

  }//*/


2

这是在服务器端(例如Node.js)上进行一些基本url参数添加或更新时使用的方法。

CoffeScript:

###
    @method addUrlParam Adds parameter to a given url. If the parameter already exists in the url is being replaced.
    @param {string} url
    @param {string} key Parameter's key
    @param {string} value Parameter's value
    @returns {string} new url containing the parameter
###
addUrlParam = (url, key, value) ->
    newParam = key+"="+value
    result = url.replace(new RegExp('(&|\\?)' + key + '=[^\&|#]*'), '$1' + newParam)
    if result is url
        result = if url.indexOf('?') != -1 then url.split('?')[0] + '?' + newParam + '&' + url.split('?')[1]
    else if url.indexOf('#') != -1 then url.split('#')[0] + '?' + newParam + '#' + url.split('#')[1]
    else url + '?' + newParam
    return result

JavaScript:

function addUrlParam(url, key, value) {
    var newParam = key+"="+value;
    var result = url.replace(new RegExp("(&|\\?)"+key+"=[^\&|#]*"), '$1' + newParam);
    if (result === url) { 
        result = (url.indexOf("?") != -1 ? url.split("?")[0]+"?"+newParam+"&"+url.split("?")[1] 
           : (url.indexOf("#") != -1 ? url.split("#")[0]+"?"+newParam+"#"+ url.split("#")[1] 
              : url+'?'+newParam));
    }
    return result;
}

var url = "http://www.example.com?foo=bar&ciao=3&doom=5#hashme";
result1.innerHTML = addUrlParam(url, "ciao", "1");
<p id="result1"></p>


2

最简单的解决方案,可以在您已经有标签的情况下工作,并自动将其删除,这样就不会继续添加相同的标签,请尽情享受

function changeURL(tag)
{
if(window.location.href.indexOf("?") > -1) {
    if(window.location.href.indexOf("&"+tag) > -1){

        var url = window.location.href.replace("&"+tag,"")+"&"+tag;
    }
    else
    {
        var url = window.location.href+"&"+tag;
    }
}else{
    if(window.location.href.indexOf("?"+tag) > -1){

        var url = window.location.href.replace("?"+tag,"")+"?"+tag;
    }
    else
    {
        var url = window.location.href+"?"+tag;
    }
}
  window.location = url;
}

然后

changeURL("i=updated");

2

Vianney Bajart的答案是正确的;但是,仅当您具有带有端口,主机,路径和查询的完整URL 时,URL才起作用:

new URL('http://server/myapp.php?id=10&enabled=true')

仅当您传递查询字符串时,URLSearchParams才有效:

new URLSearchParams('?id=10&enabled=true')

如果您有不完整或相对的URL,并且不关心基本URL,则可以按以下?方式拆分以获取查询字符串,然后像下面这样加入:

function setUrlParams(url, key, value) {
  url = url.split('?');
  usp = new URLSearchParams(url[1]);
  usp.set(key, value);
  url[1] = usp.toString();
  return url.join('?');
}

let url = 'myapp.php?id=10';
url = setUrlParams(url, 'enabled', true);  // url = 'myapp.php?id=10&enabled=true'
url = setUrlParams(url, 'id', 11);         // url = 'myapp.php?id=11&enabled=true'

与Internet Explorer不兼容。


如果您使用var u = new URL(window.location), usp = u.searchParams;,则不必使用任何花哨的字符串拆分。
amphetamachine

尽管您的解决方案适用于大多数情况,但如果参数值中带有问号,它将破坏URL:setUrlParams('https://example.com?foo=thing???&bar=baz', 'baz', 'qux') => "https://example.com?foo=thing&baz=qux???&bar=baz"
amphetamachine

1

如果您在链接或其他地方弄乱了网址,则可能还必须考虑哈希值。这是一个相当简单易懂的解决方案。可能不是最快的, 因为它使用了正则表达式...但是在99.999%的情况下,差异实际上并不重要!

function addQueryParam( url, key, val ){
    var parts = url.match(/([^?#]+)(\?[^#]*)?(\#.*)?/);
    var url = parts[1];
    var qs = parts[2] || '';
    var hash = parts[3] || '';

    if ( !qs ) {
        return url + '?' + key + '=' + encodeURIComponent( val ) + hash;
    } else {
        var qs_parts = qs.substr(1).split("&");
        var i;
        for (i=0;i<qs_parts.length;i++) {
            var qs_pair = qs_parts[i].split("=");
            if ( qs_pair[0] == key ){
                qs_parts[ i ] = key + '=' + encodeURIComponent( val );
                break;
            }
        }
        if ( i == qs_parts.length ){
            qs_parts.push( key + '=' + encodeURIComponent( val ) );
        }
        return url + '?' + qs_parts.join('&') + hash;
    }
}

不知道为什么有人拒绝了你。这是更可靠的解决方案之一,尽管它的方式比必要的方式更多。
亚当·莱格特

1

我能想到的最简单的解决方案是此方法,它将返回修改后的URI。我觉得你们大多数人都在努力工作。

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

0

好的,在这里我比较了两个函数,一个是我自己(regExp)制作的,另一个是(an​​nakata)制作的。

分割数组:

function insertParam(key, value)
{
    key = escape(key); value = escape(value);

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

    var i=kvp.length; var x; while(i--) 
    {
        x = kvp[i].split('=');

        if (x[0]==key)
        {
                x[1] = value;
                kvp[i] = x.join('=');
                break;
        }
    }

    if(i<0) {kvp[kvp.length] = [key,value].join('=');}

    //this will reload the page, it's likely better to store this until finished
    return "&"+kvp.join('&'); 
}

正则表达式方法:

function addParameter(param, value)
{
    var regexp = new RegExp("(\\?|\\&)" + param + "\\=([^\\&]*)(\\&|$)");
    if (regexp.test(document.location.search)) 
        return (document.location.search.toString().replace(regexp, function(a, b, c, d)
        {
                return (b + param + "=" + value + d);
        }));
    else 
        return document.location.search+ param + "=" + value;
}

测试案例:

time1=(new Date).getTime();
for (var i=0;i<10000;i++)
{
addParameter("test","test");
}
time2=(new Date).getTime();
for (var i=0;i<10000;i++)
{
insertParam("test","test");
}

time3=(new Date).getTime();

console.log((time2-time1)+" "+(time3-time2));

似乎即使使用最简单的解决方案(当regexp仅使用test而不输入.replace函数时),它仍然比拆分要慢...好。正则表达式有点慢,但是...呃...


正如我提到的那样,这实际上相对较慢-而且,document.location.search更清晰
annakata,2009年

0

这是我的工作。使用我的editParams()函数,您可以添加,删除或更改任何参数,然后使用内置的replaceState()函数更新URL:

window.history.replaceState('object or string', 'Title', 'page.html' + editParams('enable', 'true'));


// background functions below:

// add/change/remove URL parameter
// use a value of false to remove parameter
// returns a url-style string
function editParams (key, value) {
  key = encodeURI(key);

  var params = getSearchParameters();

  if (Object.keys(params).length === 0) {
    if (value !== false)
      return '?' + key + '=' + encodeURI(value);
    else
      return '';
  }

  if (value !== false)
    params[key] = encodeURI(value);
  else
    delete params[key];

  if (Object.keys(params).length === 0)
    return '';

  return '?' + $.map(params, function (value, key) {
    return key + '=' + value;
  }).join('&');
}

// Get object/associative array of URL parameters
function getSearchParameters () {
  var prmstr = window.location.search.substr(1);
  return prmstr !== null && prmstr !== "" ? transformToAssocArray(prmstr) : {};
}

// convert parameters from url-style string to associative array
function transformToAssocArray (prmstr) {
  var params = {},
      prmarr = prmstr.split("&");

  for (var i = 0; i < prmarr.length; i++) {
    var tmparr = prmarr[i].split("=");
    params[tmparr[0]] = tmparr[1];
  }
  return params;
}

0

最好的情况是,上述答案都不能解决查询字符串包含参数的情况,这些参数本身就是数组,因此会出现多次,例如:

http://example.com?sizes[]=a&sizes[]=b

以下功能是我编写的要更新的功能document.location.search。它使用键/值对数组作为参数,并将返回后者的修订版,您可以根据需要进行操作。我正在这样使用它:

var newParams = [
    ['test','123'],
    ['best','456'],
    ['sizes[]','XXL']
];
var newUrl = document.location.pathname + insertParams(newParams);
history.replaceState('', '', newUrl);

如果当前网址是:

http://example.com/index.php?test=replaceme&sizes[]=XL

这会让你

http://example.com/index.php?test=123&sizes[]=XL&sizes[]=XXL&best=456

功能

function insertParams(params) {
    var result;
    var ii = params.length;
    var queryString = document.location.search.substr(1);
    var kvps = queryString ? queryString.split('&') : [];
    var kvp;
    var skipParams = [];
    var i = kvps.length;
    while (i--) {
        kvp = kvps[i].split('=');
        if (kvp[0].slice(-2) != '[]') {
            var ii = params.length;
            while (ii--) {
                if (params[ii][0] == kvp[0]) {
                    kvp[1] = params[ii][1];
                    kvps[i] = kvp.join('=');
                    skipParams.push(ii);
                }
            }
        }
    }
    var ii = params.length;
    while (ii--) {
        if (skipParams.indexOf(ii) === -1) {
            kvps.push(params[ii].join('='));
        }
    }
    result = kvps.length ? '?' + kvps.join('&') : '';
    return result;
}

0

试试
正则表达式,太慢了,因此:

var SetParamUrl = function(_k, _v) {// replace and add new parameters

    let arrParams = window.location.search !== '' ? decodeURIComponent(window.location.search.substr(1)).split('&').map(_v => _v.split('=')) : Array();
    let index = arrParams.findIndex((_v) => _v[0] === _k); 
    index = index !== -1 ? index : arrParams.length;
    _v === null ? arrParams = arrParams.filter((_v, _i) => _i != index) : arrParams[index] = [_k, _v];
    let _search = encodeURIComponent(arrParams.map(_v => _v.join('=')).join('&'));

    let newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + (arrParams.length > 0 ? '?' +  _search : ''); 

    // window.location = newurl; //reload 

    if (history.pushState) { // without reload  
        window.history.pushState({path:newurl}, null, newurl);
    }

};

var GetParamUrl = function(_k) {// get parameter by key

    let sPageURL = decodeURIComponent(window.location.search.substr(1)),
        sURLVariables = sPageURL.split('&').map(_v => _v.split('='));
    let _result = sURLVariables.find(_v => _v[0] === _k);
    return _result[1];

};

例:

        // https://some.com/some_path
        GetParamUrl('cat');//undefined
        SetParamUrl('cat', "strData");// https://some.com/some_path?cat=strData
        GetParamUrl('cat');//strData
        SetParamUrl('sotr', "strDataSort");// https://some.com/some_path?cat=strData&sotr=strDataSort
        GetParamUrl('sotr');//strDataSort
        SetParamUrl('cat', "strDataTwo");// https://some.com/some_path?cat=strDataTwo&sotr=strDataSort
        GetParamUrl('cat');//strDataTwo
        //remove param
        SetParamUrl('cat', null);// https://some.com/some_path?sotr=strDataSort

0

通过JS的新成就,可以在这里向URL添加查询参数:

var protocol = window.location.protocol,
    host = '//' + window.location.host,
    path = window.location.pathname,
    query = window.location.search;

var newUrl = protocol + host + path + query + (query ? '&' : '?') + 'param=1';

window.history.pushState({path:newUrl}, '' , newUrl);

另请参阅这种可能性Moziila URLSearchParams.append()


0

这将适用于所有现代浏览器。

function insertParam(key,value) {
      if (history.pushState) {
          var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?' +key+'='+value;
          window.history.pushState({path:newurl},'',newurl);
      }
    }

0

重置所有查询字符串

var params = { params1:"val1", params2:"val2" };
let str = jQuery.param(params);

let uri = window.location.href.toString();
if (uri.indexOf("?") > 0)
   uri = uri.substring(0, uri.indexOf("?"));

console.log(uri+"?"+str);
//window.location.href = uri+"?"+str;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

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.