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

原始URL:

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

导致的网址:

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

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


当前回答

var MyApp = new Class();

MyApp.extend({
    utility: {
        queryStringHelper: function (url) {
            var originalUrl = url;
            var newUrl = url;
            var finalUrl;
            var insertParam = function (key, value) {
                key = escape(key);
                value = escape(value);

                //The previous post had the substr strat from 1 in stead of 0!!!
                var kvp = newUrl.substr(0).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('=');
                }

                finalUrl = kvp.join('&');

                return finalUrl;
            };

            this.insertParameterToQueryString = insertParam;

            this.insertParams = function (keyValues) {
                for (var keyValue in keyValues[0]) {
                    var key = keyValue;
                    var value = keyValues[0][keyValue];
                    newUrl = insertParam(key, value);
                }
                return newUrl;
            };

            return this;
        }
    }
});

其他回答

试一试 正则表达式,如此之慢,因此:

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

就我所知,上面的答案都没有解决查询字符串包含参数的情况,这些参数本身就是一个数组,因此会出现不止一次,例如:

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

如果当前url为:

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

这会让你

http://example.com/index.php?test=123&sizes[]=XL&尺寸[]=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;
}

加入@Vianney的回答https://stackoverflow.com/a/44160941/6609678

我们可以导入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

这就是我在服务器端(如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>

我是这么做的。使用我的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;
}