Change URL parameters

2018-12-31 13:01发布

问题:

I have this URL:

site.fwx?position=1&archiveid=5000&columns=5&rows=20&sorting=ModifiedTimeAsc

what I need is to be able to change the \'rows\' url param value to something i specify, lets say 10. And if the \'rows\' doesn\'t exist, I need to add it to the end of the url and add the value i\'ve already specified (10).

回答1:

I\'ve extended Sujoy\'s code to make up a function.

/**
 * http://stackoverflow.com/a/10997390/11236
 */
function updateURLParameter(url, param, paramVal){
    var newAdditionalURL = \"\";
    var tempArray = url.split(\"?\");
    var baseURL = tempArray[0];
    var additionalURL = tempArray[1];
    var temp = \"\";
    if (additionalURL) {
        tempArray = additionalURL.split(\"&\");
        for (var i=0; i<tempArray.length; i++){
            if(tempArray[i].split(\'=\')[0] != param){
                newAdditionalURL += temp + tempArray[i];
                temp = \"&\";
            }
        }
    }

    var rows_txt = temp + \"\" + param + \"=\" + paramVal;
    return baseURL + \"?\" + newAdditionalURL + rows_txt;
}

Function Calls:

var newURL = updateURLParameter(window.location.href, \'locId\', \'newLoc\');
newURL = updateURLParameter(newURL, \'resId\', \'newResId\');

window.history.replaceState(\'\', \'\', updateURLParameter(window.location.href, \"param\", \"value\"));

Updated version that also take care of the anchors on the URL.

function updateURLParameter(url, param, paramVal)
{
    var TheAnchor = null;
    var newAdditionalURL = \"\";
    var tempArray = url.split(\"?\");
    var baseURL = tempArray[0];
    var additionalURL = tempArray[1];
    var temp = \"\";

    if (additionalURL) 
    {
        var tmpAnchor = additionalURL.split(\"#\");
        var TheParams = tmpAnchor[0];
            TheAnchor = tmpAnchor[1];
        if(TheAnchor)
            additionalURL = TheParams;

        tempArray = additionalURL.split(\"&\");

        for (var i=0; i<tempArray.length; i++)
        {
            if(tempArray[i].split(\'=\')[0] != param)
            {
                newAdditionalURL += temp + tempArray[i];
                temp = \"&\";
            }
        }        
    }
    else
    {
        var tmpAnchor = baseURL.split(\"#\");
        var TheParams = tmpAnchor[0];
            TheAnchor  = tmpAnchor[1];

        if(TheParams)
            baseURL = TheParams;
    }

    if(TheAnchor)
        paramVal += \"#\" + TheAnchor;

    var rows_txt = temp + \"\" + param + \"=\" + paramVal;
    return baseURL + \"?\" + newAdditionalURL + rows_txt;
}


回答2:

I think you want the query plugin.

E.g.:

window.location.search = jQuery.query.set(\"rows\", 10);

This will work regardless of the current state of rows.



回答3:

Ben Alman has a good jquery querystring/url plugin here that allows you to manipulate the querystring easily.

As requested -

Goto his test page here

In firebug enter the following into the console

jQuery.param.querystring(window.location.href, \'a=3&newValue=100\');

It will return you the following amended url string

http://benalman.com/code/test/js-jquery-url-querystring.html?a=3&b=Y&c=Z&newValue=100#n=1&o=2&p=3

Notice the a querystring value for a has changed from X to 3 and it has added the new value.

You can then use the new url string however you wish e.g using document.location = newUrl or change an anchor link etc



回答4:

To answer my own question 4 years later, after having learned a lot. Especially that you shouldn\'t use jQuery for everything. I\'ve created a simple module that can parse/stringify a query string. This makes it easy to modify the query string.

You can use query-string as follows:

// parse the query string into an object
var q = queryString.parse(location.search);
// set the `row` property
q.rows = 10;
// convert the object to a query string
// and overwrite the existing query string
location.search = queryString.stringify(q);


回答5:

Quick little solution in pure js, no plugins needed:

function replaceQueryParam(param, newval, search) {
    var regex = new RegExp(\"([?;&])\" + param + \"[^&;]*[;&]?\");
    var query = search.replace(regex, \"$1\").replace(/&$/, \'\');

    return (query.length > 2 ? query + \"&\" : \"?\") + (newval ? param + \"=\" + newval : \'\');
}

Call it like this:

 window.location = \'/mypage\' + replaceQueryParam(\'rows\', 55, window.location.search)

Or, if you want to stay on the same page and replace multiple params:

 var str = window.location.search
 str = replaceQueryParam(\'rows\', 55, str)
 str = replaceQueryParam(\'cols\', \'no\', str)
 window.location = window.location.pathname + str

edit, thanks Luke: To remove the parameter entirely, pass false or null for the value: replaceQueryParam(\'rows\', false, params). Since 0 is also falsy, specify \'0\'.



回答6:

you can do it via normal JS also

var url = document.URL
var newAdditionalURL = \"\";
var tempArray = url.split(\"?\");
var baseURL = tempArray[0];
var aditionalURL = tempArray[1]; 
var temp = \"\";
if(aditionalURL)
{
var tempArray = aditionalURL.split(\"&\");
for ( var i in tempArray ){
    if(tempArray[i].indexOf(\"rows\") == -1){
            newAdditionalURL += temp+tempArray[i];
                temp = \"&\";
            }
        }
}
var rows_txt = temp+\"rows=10\";
var finalURL = baseURL+\"?\"+newAdditionalURL+rows_txt;


回答7:

A modern approach to this is to use native standard based URLSearchParams. It\'s supported by all major browsers, except for IE where they\'re polyfills available

const paramsString = \"site.fwx?position=1&archiveid=5000&columns=5&rows=20&sorting=ModifiedTimeAsc\"
const searchParams = new URLSearchParams(paramsString);
searchParams.set(\'rows\', 10);
console.log(searchParams.toString()); // return modified string.


回答8:

Would a viable alternative to String manipulation be to set up an html form and just modify the value of the rows element?

So, with html that is something like

<form id=\'myForm\' target=\'site.fwx\'>
    <input type=\'hidden\' name=\'position\' value=\'1\'/>
    <input type=\'hidden\' name=\'archiveid\' value=\'5000\'/>
    <input type=\'hidden\' name=\'columns\' value=\'5\'/>
    <input type=\'hidden\' name=\'rows\' value=\'20\'/>
    <input type=\'hidden\' name=\'sorting\' value=\'ModifiedTimeAsc\'/>
</form>

With the following JavaScript to submit the form

var myForm = document.getElementById(\'myForm\');
myForm.rows.value = yourNewValue;
myForm.submit();

Probably not suitable for all situations, but might be nicer than parsing the URL string.



回答9:

You can use this my library to do the job: https://github.com/Mikhus/jsurl

var url = new Url(\'site.fwx?position=1&archiveid=5000&columns=5&rows=20&sorting=ModifiedTimeAsc\');
url.query.rows = 10;
alert( url);


回答10:

I wrote a little helper function that works with any select. All you need to do is add the class \"redirectOnChange\" to any select element, and this will cause the page to reload with a new/changed querystring parameter, equal to the id and value of the select, e.g:

<select id=\"myValue\" class=\"redirectOnChange\"> 
    <option value=\"222\">test222</option>
    <option value=\"333\">test333</option>
</select>

The above example would add \"?myValue=222\" or \"?myValue=333\" (or using \"&\" if other params exist), and reload the page.

jQuery:

$(document).ready(function () {

    //Redirect on Change
    $(\".redirectOnChange\").change(function () {
        var href = window.location.href.substring(0, window.location.href.indexOf(\'?\'));
        var qs = window.location.href.substring(window.location.href.indexOf(\'?\') + 1, window.location.href.length);
        var newParam = $(this).attr(\"id\") + \'=\' + $(this).val();

        if (qs.indexOf($(this).attr(\"id\") + \'=\') == -1) {
            if (qs == \'\') {
                qs = \'?\'
            }
            else {
                qs = qs + \'&\'
            }
            qs = qs + newParam;

        }
        else {
            var start = qs.indexOf($(this).attr(\"id\") + \"=\");
            var end = qs.indexOf(\"&\", start);
            if (end == -1) {
                end = qs.length;
            }
            var curParam = qs.substring(start, end);
            qs = qs.replace(curParam, newParam);
        }
        window.location.replace(href + \'?\' + qs);
    });
});


回答11:

Here I have taken Adil Malik\'s answer and fixed the 3 issues I identified with it.

/**
 * Adds or updates a URL parameter.
 *
 * @param {string} url  the URL to modify
 * @param {string} param  the name of the parameter
 * @param {string} paramVal  the new value for the parameter
 * @return {string}  the updated URL
 */
self.setParameter = function (url, param, paramVal){
  // http://stackoverflow.com/a/10997390/2391566
  var parts = url.split(\'?\');
  var baseUrl = parts[0];
  var oldQueryString = parts[1];
  var newParameters = [];
  if (oldQueryString) {
    var oldParameters = oldQueryString.split(\'&\');
    for (var i = 0; i < oldParameters.length; i++) {
      if(oldParameters[i].split(\'=\')[0] != param) {
        newParameters.push(oldParameters[i]);
      }
    }
  }
  if (paramVal !== \'\' && paramVal !== null && typeof paramVal !== \'undefined\') {
    newParameters.push(param + \'=\' + encodeURI(paramVal));
  }
  if (newParameters.length > 0) {
    return baseUrl + \'?\' + newParameters.join(\'&\');
  } else {
    return baseUrl;
  }
}


回答12:

Another variation on Sujoy\'s answer. Just changed the variable names & added a namespace wrapper:

window.MyNamespace = window.MyNamespace  || {};
window.MyNamespace.Uri = window.MyNamespace.Uri || {};

(function (ns) {

    ns.SetQueryStringParameter = function(url, parameterName, parameterValue) {

        var otherQueryStringParameters = \"\";

        var urlParts = url.split(\"?\");

        var baseUrl = urlParts[0];
        var queryString = urlParts[1];

        var itemSeparator = \"\";
        if (queryString) {

            var queryStringParts = queryString.split(\"&\");

            for (var i = 0; i < queryStringParts.length; i++){

                if(queryStringParts[i].split(\'=\')[0] != parameterName){

                    otherQueryStringParameters += itemSeparator + queryStringParts[i];
                    itemSeparator = \"&\";
                }
            }
        }

        var newQueryStringParameter = itemSeparator + parameterName + \"=\" + parameterValue;

        return baseUrl + \"?\" + otherQueryStringParameters + newQueryStringParameter;
    };

})(window.MyNamespace.Uri);

Useage is now:

var changedUrl = MyNamespace.Uri.SetQueryStringParameter(originalUrl, \"CarType\", \"Ford\");


回答13:

I too have written a library for getting and setting URL query parameters in JavaScript.

Here is an example of its usage.

var url = Qurl.create()
  , query
  , foo
  ;

Get query params as an object, by key, or add/change/remove.

// returns { foo: \'bar\', baz: \'qux\' } for ?foo=bar&baz=qux
query = url.query();

// get the current value of foo
foo = url.query(\'foo\');

// set ?foo=bar&baz=qux
url.query(\'foo\', \'bar\');
url.query(\'baz\', \'qux\');

// unset foo, leaving ?baz=qux
url.query(\'foo\', false); // unsets foo


回答14:

Here is what I do. Using my editParams() function, you can add, remove, or change any parameter, then use the built in replaceState() function to update the URL:

window.history.replaceState(\'object or string\', \'Title\', \'page.html\' + editParams(\'sorting\', ModifiedTimeAsc));


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


回答15:

I was looking for the same thing and found: https://github.com/medialize/URI.js which is quite nice :)

-- Update

I found a better package: https://www.npmjs.org/package/qs it also deals with arrays in get params.



回答16:

I know this is an old question. I have enhanced the function above to add or update query params. Still a pure JS solution only.

                      function addOrUpdateQueryParam(param, newval, search) {

                        var questionIndex = search.indexOf(\'?\');

                        if (questionIndex < 0) {
                            search = search + \'?\';
                            search = search + param + \'=\' + newval;
                            return search;
                        }

                        var regex = new RegExp(\"([?;&])\" + param + \"[^&;]*[;&]?\");
                        var query = search.replace(regex, \"$1\").replace(/&$/, \'\');

                        var indexOfEquals = query.indexOf(\'=\');

                        return (indexOfEquals >= 0 ? query + \'&\' : query + \'\') + (newval ? param + \'=\' + newval : \'\');
                    }


回答17:

my function support removing param

function updateURLParameter(url, param, paramVal, remove = false) {
        var newAdditionalURL = \'\';
        var tempArray = url.split(\'?\');
        var baseURL = tempArray[0];
        var additionalURL = tempArray[1];
        var rows_txt = \'\';

        if (additionalURL)
            newAdditionalURL = decodeURI(additionalURL) + \'&\';

        if (remove)
            newAdditionalURL = newAdditionalURL.replace(param + \'=\' + paramVal, \'\');
        else
            rows_txt = param + \'=\' + paramVal;

        window.history.replaceState(\'\', \'\', (baseURL + \"?\" + newAdditionalURL + rows_txt).replace(\'?&\', \'?\').replace(\'&&\', \'&\').replace(/\\&$/, \'\'));
    }


回答18:

This is the modern way todo it:

function setGetParam(key,value) {
  if (history.pushState) {
    var params = new URLSearchParams(window.location.search);
    params.set(key, value);
    var newUrl = window.location.protocol + \"//\" + window.location.host + window.location.pathname + \'?\' + params.toString();
    window.history.pushState({path:newUrl},\'\',newUrl);
  }
}


回答19:

My snippet with URI decoding / encoding:

function isDefined(object) {
	return object !== undefined && object !== null;
}

function isNotEmpty(string) {
	return isDefined(string) && string.length > 0;
}

/**
 * Update or add the specified URL parameter.
 * <p>
 * @param {String} name
 * @param {String} value
 */
function updateUrlParam(name, value) {
	// Get the path and the query
	var urlInfo = decodeURI(window.location.href).split(\'?\');
	var path = urlInfo[0];
	var query = urlInfo[1];

	// Build the query
	var params = \'\';
	var anchor = null;
	if (isNotEmpty(query)) {
		var queryInfo = query.split(\'#\');
		query = queryInfo[0];
		anchor = queryInfo[1];

		queryInfo = query.split(\'&\');
		for (var i = 0; i < queryInfo.length; ++i) {
			if (queryInfo[i].split(\'=\')[0] !== name) {
				params += \'&\' + queryInfo[i];
			}
		}
	} else {
		var queryInfo = path.split(\'#\');
		query = queryInfo[0];
		anchor = queryInfo[1];
		if (isNotEmpty(query)) {
			path = query;
		}
	}
	query = \'?\' + name + \'=\' + value + params;
	if (isNotEmpty(anchor)) {
		query += \'#\' + anchor;
	}

	// Replace the URL
	window.history.replaceState(\'\', \'\', encodeURI(path + query));
}