使用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个回答

10

该解决方案可以在不重新加载页面的情况下,通过更新搜索参数来更新窗口的当前URL。这种方法在PWA/SPA环境中非常有用。

function setURLSearchParam(key, value) {
  const url = new URL(window.location.href);
  url.searchParams.set(key, value);
  window.history.pushState({ path: url.href }, '', url.href);
}

9
这是一种简单的添加查询参数的方法:
const query = new URLSearchParams(window.location.search);
query.append("enabled", "true");

就是这样 更多内容请看这里.

请注意支持规范


4
似乎在任何版本的Internet Explorer中都不支持此功能。 - MAXE
1
非常适合移动设备。当Internet Explorer出现在我的移动设备上时,我会扔掉它。 :-) - stillatmylinux
@MAXE,你是对的,IE/EDGE支持有限。可在此链接查看支持情况:http://caniuse.com/#feat=urlsearchparams - T04435

9
有时我们在URL末尾看到了?符号,我发现有些解决方案会生成file.php?&foo=bar之类的结果。我想出了自己的解决方案,它能完美地达到我的要求!
location.origin + location.pathname + location.search + (location.search=='' ? '?' : '&') + 'lang=ar'

注意:在IE浏览器中,location.origin无法使用,这里是它的修复方法


7
以下函数将帮助您向URL添加、更新和删除参数。
//示例1:
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

//示例2

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

//示例4

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

非常感谢,这个很好用 :D - Vipertecpro
哇,这太长了。 - David Spector

7

在@Vianney的回答中补充一点https://dev59.com/KXRB5IYBdhLWcg3w3K4J#44160941

我们可以按照以下方式导入Node中内置的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/en-US/docs/Web/API/URL https://developer.mozilla.org/en/docs/Web/API/URLSearchParams


6

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

它是一个处理javascript中URI和查询字符串的项目。

该项目使用了Steven Levithan编写的出色parseUri正则表达式库。您可以安全地解析各种形状和大小的URL,即使它们无效或丑陋。


404 - 请求的URL /p/jsuri/ 在服务器上未找到。这就是我们所知道的全部。 - Aligma
1
看起来它已经被移动了。我已经更新了URL。祝你好运! - Charlie Liang Yuan
请在您的回答中包含相关细节,而不仅仅是链接。 - jhpratt

6

它处理以下类型的URL:

  • 空的URL
  • 没有任何参数的URL
  • 已经有一些参数的URL
  • 结尾有?,但同时没有任何参数的URL

它不处理以下类型的URL:

  • 带有片段标识符的URL(即哈希,#)
  • 如果URL已经具有所需的查询参数,则会出现重复

适用于:

  • Chrome 32+
  • Firefox 26+
  • Safari 7.1+
function appendQueryParameter(url, name, value) {
    if (url.length === 0) {
        return;
    }

    let rawURL = url;

    // URL with `?` at the end and without query parameters
    // leads to incorrect result.
    if (rawURL.charAt(rawURL.length - 1) === "?") {
        rawURL = rawURL.slice(0, rawURL.length - 1);
    }

    const parsedURL = new URL(rawURL);
    let parameters = parsedURL.search;

    parameters += (parameters.length === 0) ? "?" : "&";
    parameters = (parameters + name + "=" + value);

    return (parsedURL.origin + parsedURL.pathname + parameters);
}

使用ES6模板字符串的版本。

适用于:

  • Chrome 41+
  • Firefox 32+
  • Safari 9.1+
function appendQueryParameter(url, name, value) {
    if (url.length === 0) {
        return;
    }

    let rawURL = url;

    // URL with `?` at the end and without query parameters
    // leads to incorrect result.
    if (rawURL.charAt(rawURL.length - 1) === "?") {
        rawURL = rawURL.slice(0, rawURL.length - 1);
    }

    const parsedURL = new URL(rawURL);
    let parameters = parsedURL.search;

    parameters += (parameters.length === 0) ? "?" : "&";
    parameters = `${parameters}${name}=${value}`;

    return `${parsedURL.origin}${parsedURL.pathname}${parameters}`;
}

更新的代码支持多个参数。function insertCustomParams(input) { var output = []; var i = 0; Object.entries(input).forEach(function (k, v) { output[i++] = k.join("="); });var kvp = document.location.search.substr(1).split("&"); var j = 0; for (; j < kvp.length; j++) { let pair = kvp[j].split("="); if (!Object.keys(input).includes(pair[0])) { output[i++] = pair.join("="); } } document.location.search = output.join("&");} - Reneesh Kurian

6
这是我的尝试,但我会使用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。我一直在使用它,效果非常好!我上传了一个Gist,其中包含我自己版本的代码,编辑后更加简洁并且通过了JSHint验证。https://gist.github.com/jonathanconway/02a183920506acd9890a - Jonathan

6
尝试一下。
// 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);
            }
        }

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

3

Vianney Bajart的回答是正确的;然而,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

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