99

I've been looking for an efficient way to do this but haven't been able to find it, basically what I need is that given this url for example:

http://localhost/mysite/includes/phpThumb.php?src=http://media2.jupix.co.uk/v3/clients/4/properties/795/IMG_795_1_large.jpg&w=592&aoe=1&q=100

I'd like to be able to change the URL in the src parameter with another value using javascript or jquery, is this possible?

1

20 Answers 20

163

The following solution combines other answers and handles some special cases:

  • The parameter does not exist in the original url
  • The parameter is the only parameter
  • The parameter is first or last
  • The new parameter value is the same as the old
  • The url ends with a ? character
  • \b ensures another parameter ending with paramName won't be matched

Solution:

function replaceUrlParam(url, paramName, paramValue)
{
    if (paramValue == null) {
        paramValue = '';
    }
    var pattern = new RegExp('\\b('+paramName+'=).*?(&|#|$)');
    if (url.search(pattern)>=0) {
        return url.replace(pattern,'$1' + paramValue + '$2');
    }
    url = url.replace(/[?#]$/,'');
    return url + (url.indexOf('?')>0 ? '&' : '?') + paramName + '=' + paramValue;
}

Known limitations:

Sign up to request clarification or add additional context in comments.

11 Comments

This is more appropriate solution than the one marked with the highest vote.
Your function will append a duplicate parameter in the case it is invoked with a parameter name and value that already exists in the URL.
Ryan, you were right about that. I have edited the function to handle also that scenario.
Thanks for making the update. I just ran into the same bug and was about to get my hands dirty with a fix, but your fix came to the rescue.
I just added url = url.replace(/\?$/,''); to solve the 2nd limitation. Fiddle: jsfiddle.net/ucubvgws
|
130

Nowdays that's possible with native JS

var href = new URL('https://google.com?q=cats');
href.searchParams.set('q', 'dogs');
console.log(href.toString()); // https://google.com/?q=dogs

2 Comments

Simple and clean. Perfect!
This is a much cleaner approach. It even takes care of encoding the param value.
60

Wouldn't this be a better solution?

var text = 'http://localhost/mysite/includes/phpThumb.php?src=http://media2.jupix.co.uk/v3/clients/4/properties/795/IMG_795_1_large.jpg&w=592&aoe=1&q=100';
var newSrc = 'www.google.com';
var newText = text.replace(/(src=).*?(&)/,'$1' + newSrc + '$2');

EDIT:

added some clarity in code and kept 'src' in the resulting link

$1 represents first part within the () (i.e) src= and $2 represents the second part within the () (i.e) &, so this indicates you are going to change the value between src and &. More clear, it should be like this:

src='changed value'& // this is to be replaced with your original url

ADD-ON for replacing all the ocurrences:

If you have several parameters with the same name, you can append to the regex global flag, like this text.replace(/(src=).*?(&)/g,'$1' + newSrc + '$2'); and that will replaces all the values for those params that shares the same name.

8 Comments

Doesn't handle the general case of replacing the last parameter. I changed the regex to /(src=).*?(&)?/ for a similar problem.
@ZenMaster Perfect :), can you explain meaning of text.replace(/(src=).*?(&)/,'$1' + newSrc + '$2');
2 capturing groups... See more here: stackoverflow.com/questions/3512471/non-capturing-group
Doesn't handle the case for the last parameter.
I used the RegExp /(src=).*?(&|$)/ to address the last-parameter-problem.
|
33

Javascript now give a very useful functionnality to handle url parameters: URLSearchParams

var searchParams = new URLSearchParams(window.location.search);
searchParams.set('src','newSrc')
var newParams = searchParams.toString()

4 Comments

Worked perfectly. No IE support though .
This is true, no IE and Mobile Safari support at this time. But reliable solutions can be found there or there.
Nowdays that's possible with native JS
How can I use this to replace an existing set of parameters in a URL?
14

In modern browsers (everything except IE9 and below), our lives are a little easier now with the new URL api

var url = new window.URL(document.location); // fx. http://host.com/endpoint?abc=123
url.searchParams.set("foo", "bar");
console.log(url.toString()); // http://host/endpoint?abc=123&foo=bar
url.searchParams.set("foo", "ooft");
console.log(url.toString()); // http://host/endpoint?abc=123&foo=ooft

2 Comments

N.B URL constructor is not available on all IE browsers developer.mozilla.org/en-US/docs/Web/API/URL/URL
This is the easiest and most up to date answer.
10
// Construct URLSearchParams object instance from current URL querystring.
var queryParams = new URLSearchParams(window.location.search);
 
// Set new or modify existing parameter value. 
queryParams.set("myParam", "myValue");
 
// Replace current querystring with the new one.
history.replaceState(null, null, "?"+queryParams.toString());

Alternatively instead of modifying current history entry using replaceState() we can use pushState() method to create a new one:

history.pushState(null, null, "?"+queryParams.toString());

Comments

8

Here is modified stenix's code, it's not perfect but it handles cases where there is a param in url that contains provided parameter, like:

/search?searchquery=text and 'query' is provided.

In this case searchquery param value is changed.

Code:

function replaceUrlParam(url, paramName, paramValue){
    var pattern = new RegExp('(\\?|\\&)('+paramName+'=).*?(&|$)')
    var newUrl=url
    if(url.search(pattern)>=0){
        newUrl = url.replace(pattern,'$1$2' + paramValue + '$3');
    }
    else{
        newUrl = newUrl + (newUrl.indexOf('?')>0 ? '&' : '?') + paramName + '=' + paramValue
    }
    return newUrl
}

2 Comments

I added a \b in my solution to solve the problem. Thanks for pointing it out.
This will fail when the url is "?q=1&x=", it will return "?q=1?", I think the condition in the else should be >=0 instead of >0 to resolve this.
4

If you are having very narrow and specific use-case like replacing a particular parameter of given name that have alpha-numeric values with certain special characters capped upto certain length limit, you could try this approach:

urlValue.replace(/\bsrc=[0-9a-zA-Z_@.#+-]{1,50}\b/, 'src=' + newValue);

Example:

let urlValue = 'www.example.com?a=b&src=test-value&p=q';
const newValue = 'sucess';
console.log(urlValue.replace(/\bsrc=[0-9a-zA-Z_@.#+-]{1,50}\b/, 'src=' + newValue));
// output - www.example.com?a=b&src=sucess&p=q

Comments

2

I have get best solution to replace the URL parameter.

Following function will replace room value to 3 in the following URL.

http://example.com/property/?min=50000&max=60000&room=1&property_type=House

var newurl = replaceUrlParam('room','3');
history.pushState(null, null, newurl);

function replaceUrlParam(paramName, paramValue){
    var url = window.location.href;

    if (paramValue == null) {
        paramValue = '';
    }

    var pattern = new RegExp('\\b('+paramName+'=).*?(&|#|$)');
    if (url.search(pattern)>=0) {
        return url.replace(pattern,'$1' + paramValue + '$2');
    }

    url = url.replace(/[?#]$/,'');
    return url + (url.indexOf('?')>0 ? '&' : '?') + paramName + '=' + paramValue;
}

Output

http://example.com/property/?min=50000&max=60000&room=3&property_type=House

1 Comment

Why are you reposting Stenix answer?
2

Editing a Parameter The set method of the URLSearchParams object sets the new value of the parameter.

After setting the new value you can get the new query string with the toString() method. This query string can be set as the new value of the search property of the URL object.

The final new url can then be retrieved with the toString() method of the URL object.


var query_string = url.search;

var search_params = new URLSearchParams(query_string); 

// new value of "id" is set to "101"
search_params.set('id', '101');

// change the search property of the main url
url.search = search_params.toString();

// the new url string
var new_url = url.toString();

// output : http://demourl.com/path?id=101&topic=main
console.log(new_url);

Source - https://usefulangle.com/post/81/javascript-change-url-parameters

2 Comments

The set method also removes all other params.
Not at all. The set method only sets id parameter. Any other parameter is untouched.
1

UpdatE: Make it into a nice function for you: http://jsfiddle.net/wesbos/KH25r/1/

function swapOutSource(url, newSource) {
    params = url.split('&');
    var src = params[0].split('=');
    params.shift();
    src[1] = newSource;
    var newUrl = ( src.join('=') + params.join('&')); 
    return newUrl; 
}

Then go at it!

var newUrl = swapOutSource("http://localhost/mysite/includes/phpThumb.php?src=http://media2.jupix.co.uk/v3/clients/4/properties/795/IMG_795_1_large.jpg&w=592&aoe=1&q=100","http://link/to/new.jpg");


console.log(newUrl);

1 Comment

The problem here is that you are always replacing the 1st parameter. So if I rearrange the string to be "localhost/mysite/includes/phpThumb.php?q=100&src=http://…" All the sudden it will break...
1

If you look closely you'll see two surprising things about URLs: (1) they seem simple, but the details and corner cases are actually hard, (2) Amazingly JavaScript doesn't provide a full API for making working with them any easier. I think a full-fledged library is in order to avoid people re-inventing the wheel themselves or copying some random dude's clever, but likely buggy regex code snippet. Maybe try URI.js (http://medialize.github.io/URI.js/)

1 Comment

As someone that doesn't know regex, I am afraid of 'some random dude's clever, but likely buggy regex code snippet' hahah.
1

I use this method which:

  • replace the url in the history
  • return the value of the removed parameter

    function getUrlParameterAndRemoveParameter(paramName) {
        var url = window.location.origin + window.location.pathname;
        var s = window.location.search.substring(1);
        var pArray = (s == "" ? [] : s.split('&'));
    
        var paramValue = null;
        var pArrayNew = [];
        for (var i = 0; i < pArray.length; i++) {
            var pName = pArray[i].split('=');
            if (pName[0] === paramName) {
                paramValue = pName[1] === undefined ? true : decodeURIComponent(pName[1]);
            }
            else {
                pArrayNew.push(pArray[i]);
            }
        }
    
        url += (pArrayNew.length == 0 ? "" : "?" + pArrayNew.join('&'));
        window.history.replaceState(window.history.state, document.title, url);
    
        return paramValue;
    }
    

Comments

1

2020 answer since I was missing the functionality to automatically delete a parameter, so:

Based on my favorite answer https://stackoverflow.com/a/20420424/6284674 : I combined it with the ability to:

  • automatically delete an URL param if the value if null or '' based on answer https://stackoverflow.com/a/25214672/6284674

  • optionally push the updated URL directly in the window.location bar

  • IE support since it's only using regex and no URLSearchParams

JSfiddle: https://jsfiddle.net/MickV/zxc3b47u/


function replaceUrlParam(url, paramName, paramValue){
    if(paramValue == null || paramValue == "")
        return url
        .replace(new RegExp('[?&]' + paramValue + '=[^&#]*(#.*)?$'), '$1')
        .replace(new RegExp('([?&])' + paramValue + '=[^&]*&'), '$1');   
    url = url.replace(/\?$/,'');
    var pattern = new RegExp('\\b('+paramName+'=).*?(&|$)')
    if(url.search(pattern)>=0){
        return url.replace(pattern,'$1' + paramValue + '$2');
    }
    return url + (url.indexOf('?')>0 ? '&' : '?') + paramName + '=' + paramValue 
}

// Orginal URL (default jsfiddle console URL)
//https://fiddle.jshell.net/_display/?editor_console=true

console.log(replaceUrlParam(window.location.href,'a','2'));   
//https://fiddle.jshell.net/_display/?editor_console=true&a=2

console.log(replaceUrlParam(window.location.href,'a',''));   
//https://fiddle.jshell.net/_display/?editor_console=true

console.log(replaceUrlParam(window.location.href,'a',3));   
//https://fiddle.jshell.net/_display/?editor_console=true&a=3

console.log(replaceUrlParam(window.location.href,'a', null));   
//https://fiddle.jshell.net/_display/?editor_console=true&

//Optionally also update the replaced URL in the window location bar
//Note: This does not work in JSfiddle, but it does in a normal browser
function pushUrl(url){
    window.history.pushState("", "", replaceUrlParam(window.location.href,'a','2'));   
}


pushUrl(replaceUrlParam(window.location.href,'a','2'));   
//https://fiddle.jshell.net/_display/?editor_console=true&a=2

pushUrl(replaceUrlParam(window.location.href,'a',''));   
//https://fiddle.jshell.net/_display/?editor_console=true

pushUrl(replaceUrlParam(window.location.href,'a',3));   
//https://fiddle.jshell.net/_display/?editor_console=true&a=3

pushUrl(replaceUrlParam(window.location.href,'a', null));   
//https://fiddle.jshell.net/_display/?editor_console=true&

Comments

0

In addition to @stenix, this worked perfectly to me

 url =  window.location.href;
    paramName = 'myparam';
        paramValue = $(this).val();
        var pattern = new RegExp('('+paramName+'=).*?(&|$)') 
        var newUrl = url.replace(pattern,'$1' + paramValue + '$2');
        var n=url.indexOf(paramName);
        alert(n)
        if(n == -1){
            newUrl = newUrl + (newUrl.indexOf('?')>0 ? '&' : '?') + paramName + '=' + paramValue 
        }
        window.location.href = newUrl;

Here no need to save the "url" variable, just replace in current url

1 Comment

how about replacing multiply param?
0

How about something like this:

<script>
function changeQueryVariable(keyString, replaceString) {
    var query = window.location.search.substring(1);
    var vars = query.split("&");
    var replaced = false;
    for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split("=");
        if (pair[0] == keyString) {
            vars[i] = pair[0] + "="+ replaceString;
            replaced = true;
        }
    }
    if (!replaced) vars.push(keyString + "=" + replaceString);
    return vars.join("&");
}
</script>

2 Comments

The only problem is that the URL doesn't come from the browser but from a variable, so I can't use the search method :(
That is okay, you can do the same thing with regex. Here is an example: stackoverflow.com/questions/901115/…
0

try this

var updateQueryStringParam = function (key, value) {

    var baseUrl = [location.protocol, '//', location.host, location.pathname].join(''),
        urlQueryString = document.location.search,
        newParam = key + '=' + value,
        params = '?' + newParam;

    // If the "search" string exists, then build params from it
    if (urlQueryString) {
        var updateRegex = new RegExp('([\?&])' + key + '[^&]*');
        var removeRegex = new RegExp('([\?&])' + key + '=[^&;]+[&;]?');

        if( typeof value == 'undefined' || value == null || value == '' ) { // Remove param if value is empty
            params = urlQueryString.replace(removeRegex, "$1");
            params = params.replace( /[&;]$/, "" );

        } else if (urlQueryString.match(updateRegex) !== null) { // If param exists already, update it
            params = urlQueryString.replace(updateRegex, "$1" + newParam);

        } else { // Otherwise, add it to end of query string
            params = urlQueryString + '&' + newParam;
        }
    }

    // no parameter was set so we don't need the question mark
    params = params == '?' ? '' : params;

    window.history.replaceState({}, "", baseUrl + params);
};

Comments

0

A solution without Regex, a little bit easier on the eye, one I was looking for

This supports ports, hash parameters etc.

Uses browsers attribute element as a parser.

function setUrlParameters(url, parameters) {
    var parser = document.createElement('a');
    parser.href = url;

    url = "";

    if (parser.protocol) {
        url += parser.protocol + "//";
    }

    if (parser.host) {
        url += parser.host;
    }

    if (parser.pathname) {
        url += parser.pathname;
    }

    var queryParts = {};

    if (parser.search) {
        var search = parser.search.substring(1);

        var searchParts = search.split("&");
        for (var i = 0; i < searchParts.length; i++) {
            var searchPart = searchParts[i];

            var whitespaceIndex = searchPart.indexOf("=");

            if (whitespaceIndex !== -1) {
                var key = searchPart.substring(0, whitespaceIndex);
                var value = searchPart.substring(whitespaceIndex + 1);

                queryParts[key] = value;
            } else {
                queryParts[searchPart] = false;
            }
        }
    }

    var parameterKeys = Object.keys(parameters);

    for (var i = 0; i < parameterKeys.length; i++) {
        var parameterKey = parameterKeys[i];

        queryParts[parameterKey] = parameters[parameterKey];
    }


    var queryPartKeys = Object.keys(queryParts);

    var query = "";

    for (var i = 0; i < queryPartKeys.length; i++) {
        if (query.length === 0) {
            query += "?";
        }
        if (query.length > 1) {
            query += "&";
        }

        var queryPartKey = queryPartKeys[i];

        query += queryPartKey;

        if (queryParts[queryPartKey]) {
            query += "=";

            query += queryParts[queryPartKey];
        }
    }

    url += query;

    if (parser.hash) {
        url += parser.hash;
    }

    return url;
}

Comments

0

Here is function which replaces url param with paramVal

function updateURLParameter(url, param, paramVal){
        if(!url.includes('?')){
            return url += '?' + param + '=' + paramVal;
        }else if(!url.includes(param)){
            return url += '&' + param + '=' + paramVal;
        }else {
            let paramStartIndex = url.search(param);
            let paramEndIndex = url.indexOf('&', paramStartIndex);
            if (paramEndIndex == -1){
                paramEndIndex = url.length;
            }
            let brands = url.substring(paramStartIndex, paramEndIndex);
    
            return url.replace(brands, param + '=' + paramVal);
        }
    }

Comments

0

A lengthier, but maybe more flexible, answer that relies on two functions. The first one produces a key/value dictionary with all the parameters, the other one doing the substitution itself. This should work on old browsers, and can also create the parameter when it doesn't exist.

var get_all_params=function(url)
{               
    var regexS = /(?<=&|\?)([^=]*=[^&#]*)/;
    var regex = new RegExp( regexS,'g' );
    var results = url.match(regex);
    if(results==null)
    {
        return {};
    }
    else
    {
        returned={};
        for(i=0;i<results.length;i++)
        {
            var tmp=results[i];                
            var regexS2="([^=]+)=([^=]+)";
            var regex2 = new RegExp( regexS2 );
            var results2 = regex2.exec(tmp );                
            returned[results2[1]]=results2[2];
        }
        return returned;
    }   
}

var replace_param=function(url, param, value)
{
    var get_params=get_all_params(url);
    var base_url=url.split("?");
    get_params[param]=value;
    var new_params=Array();
    for(key in get_params)
    {
        new_params.push(key+"="+get_params[key]);
    }
    return base_url[0]+"?"+new_params.join("&");
}

Exemple of call :

var url ="https://geoserver.xxx.com/geoserver/project?service=WFS&version=1.0.0&request=GetFeature&typename=localities";
url=replace_param(url, "service","WMS");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.