使用JavaScript向URL添加参数

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

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

生成的URL:

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

寻找一种JavaScript函数,它可以解析URL的每个参数,然后添加新参数或更新已存在参数的值。

你有没有搜索过JavaScript URL解析器?你可以自己制作,按每个“&”字符进行分割,但使用现有的代码可能更容易。 - csl
1
我曾经遇到过类似的情况,我发现Peter Bromberg的这篇文章非常有帮助: - Cerebrus
2
window.history.pushState('page2', '标题', document.location+'/page2.php');可以在不加载页面的情况下完成您的工作。 - Rutunj sheladiya
2
这个问题在这里有更好的答案 https://dev59.com/Q2w05IYBdhLWcg3w6F8w#6954277 - rkb
难以置信,JS 这种可怜的语言居然没有原生支持这个功能。 - bohr
这是一个非常好用且轻量级的库:https://medialize.github.io/URI.js/ - Piotr Kowalski
37个回答

3
下面内容涉及:
  • 合并重复的查询字符串参数
  • 适用于绝对和相对URL
  • 可在浏览器和Node中使用
/**
 * Adds query params to existing URLs (inc merging duplicates)
 * @param {string} url - src URL to modify
 * @param {object} params - key/value object of params to add
 * @returns {string} modified URL
 */
function addQueryParamsToUrl(url, params) {

    // if URL is relative, we'll need to add a fake base
    var fakeBase = !url.startsWith('http') ? 'http://fake-base.com' : undefined;
    var modifiedUrl = new URL(url || '', fakeBase);

    // add/update params
    Object.keys(params).forEach(function(key) {
        if (modifiedUrl.searchParams.has(key)) {
            modifiedUrl.searchParams.set(key, params[key]);
        }
        else {
            modifiedUrl.searchParams.append(key, params[key]);
        }
    });

    // return as string (remove fake base if present)
    return modifiedUrl.toString().replace(fakeBase, '');
}

示例:

// returns /guides?tag=api
addQueryParamsToUrl('/guides?tag=hardware', { tag:'api' })

// returns https://orcascan.com/guides?tag=api
addQueryParamsToUrl('https://orcascan.com/guides?tag=hardware', { tag: 'api' })

3

Typescript的解决方案:

// get current url query string params
  const urlParams = new URLSearchParams(window.location.search);

// append as there could be other query string params
  urlParams.set("paramKey", "paramValue");

// this will reload the page and set query string params.. 
// ex: http://localhost:3000/dashboard?paramKey=paramValue
  window.location.search = urlParams.toString();

2

我喜欢Mehmet Fatih Yı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

请在您的回答中包含相关细节,而不仅仅是链接。 - jhpratt

2

当涉及到一些基本的url参数添加或服务器端更新时,如Node.js时,我使用以下内容。

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
const params = new URLSearchParams(window.location.search);

params.delete(key)
window.history.replaceState({}, "", decodeURIComponent(`${window.location.pathname}?${params}`));

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

1

我分享我的解决方案,因为它支持相对URL和绝对URL。除此之外,它与顶部答案中使用的Web API相同。

/**
 * updates a relative or absolute
 * by setting the search query with
 * the passed key and value.
 */
export const setQueryParam = (url, key, value) => {
  const dummyBaseUrl = 'https://dummy-base-url.com';
  const result = new URL(url, dummyBaseUrl);
  result.searchParams.set(key, value);
  return result.toString().replace(dummyBaseUrl, '');
};

还有一些 Jest 测试:

// some jest tests
describe('setQueryParams', () => {
  it('sets param on relative url with base path', () => {
    // act
    const actual = setQueryParam(
      '/', 'ref', 'some-value',
    );
    // assert
    expect(actual).toEqual('/?ref=some-value');
  });
  it('sets param on relative url with no path', () => {
    // act
    const actual = setQueryParam(
      '', 'ref', 'some-value',
    );
    // assert
    expect(actual).toEqual('/?ref=some-value');
  });
  it('sets param on relative url with some path', () => {
    // act
    const actual = setQueryParam(
      '/some-path', 'ref', 'some-value',
    );
    // assert
    expect(actual).toEqual('/some-path?ref=some-value');
  });
  it('overwrites existing param', () => {
    // act
    const actual = setQueryParam(
      '/?ref=prev-value', 'ref', 'some-value',
    );
    // assert
    expect(actual).toEqual('/?ref=some-value');
  });
  it('sets param while another param exists', () => {
    // act
    const actual = setQueryParam(
      '/?other-param=other-value', 'ref', 'some-value',
    );
    // assert
    expect(actual).toEqual('/?other-param=other-value&ref=some-value');
  });
  it('honors existing base url', () => {
    // act
    const actual = setQueryParam(
      'https://base.com', 'ref', 'some-value',
    );
    // assert
    expect(actual).toEqual('https://base.com/?ref=some-value');
  });
  it('honors existing base url with some path', () => {
    // act
    const actual = setQueryParam(
      'https://base.com/some-path', 'ref', 'some-value',
    );
    // assert
    expect(actual).toEqual('https://base.com/some-path?ref=some-value');
  });
});


1
如果你在链接或其他地方胡乱操作URL,可能也需要考虑哈希。这里有一个相当简单易懂的解决方案。虽然它使用了正则表达式,但很可能不是最快的......但在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;
    }
}

不确定为什么有人给你点了踩。这是其中一种更可靠的解决方案,尽管它比必要的代码多得多。 - Adam Leggett

0

随着JavaScript的新成果,以下是如何向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()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接