Alterar parâmetros de URL

189

Eu tenho este URL:

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

o que eu preciso é ser capaz de alterar o valor do parâmetro da URL de 'linhas' para algo que eu especificar, digamos 10. E se as 'linhas' não existirem, eu preciso adicioná-lo ao final do URL e adicionar o valor que eu já especifiquei (10).

Sindre Sorhus
fonte
2
Um leve, resposta não-plugin: stackoverflow.com/a/10997390/11236
ripper234
11
Não acredito que seja 2013 e não há uma maneira melhor de fazê-lo, como algo incorporado às principais bibliotecas do navegador.
Tyler Collier
Veja a minha resposta para uma solução moderna: stackoverflow.com/a/19965480/64949
Sindre Sorhus
6
@TylerCollier meados de 2015. agora e ainda nada :(
Tejas Manohar
3
Parece que estamos chegando lá ... developer.mozilla.org/pt-BR/docs/Web/API/URLSearchParams/…
chris

Respostas:

111

Estendi o código de Sujoy para criar uma função.

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

Chamadas de função:

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

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

Versão atualizada que também cuida das âncoras no 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;
}
Adil Malik
fonte
Parece que não consigo fazer isso funcionar. Aqui está o meu código: jsfiddle.net/Draven/tTPYL/1 A URL teria a aparência http://www.domain.com/index.php?action=my_action&view-all=Yese preciso alterar o valor "ver tudo". Minha pergunta SO que foi encerrada: stackoverflow.com/questions/13025880/…
Draven
Você tem certeza? funcionou para mim facilmente. Confira aqui: jsfiddle.net/mw49a
Adil Malik
1
Use "var i = 0" em vez de "i = 0" para impedir a criação / modificação de i como uma variável global.
Jonathan Aquino
1
Outros problemas com esta função: (1) paramVal não é codificado em uri. (2) se paramVal for nulo, você terá foo = null. Deve ser foo = (ou melhor ainda, remova foo completamente).
Jonathan Aquino
Isso tornou minha vida muito mais fácil. Muito obrigado companheiro!
28616 boydenhartog
97

Eu acho que você quer o plugin de consulta .

Por exemplo:

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

Isso funcionará independentemente do estado atual das linhas.

Matthew Flaschen
fonte
Mofle, isso ocorre porque o plug-in Query usa decodeURIComponent e decodeURIComponent ("% F8") é inválido.
Matthew Flaschen
2
Tire essas coisas estranhas do seu URL. Ou, em outras palavras, "altere sua string de consulta para usar apenas caracteres UTF-8 válidos". :) F8 por si só não é um caractere UTF-8 válido.
21415 Matthew Flaschen
Existe uma maneira de recuperar o URL base deste plugin? Por exemplo, se meu URL for ' youtube.com/watch?v=PZootaxRh3M ', obtenha ' youtube.com/watch '
Matt Norris
3
@Wraith, você não precisa de um plugin para isso. É só window.location.pathname.
Matthew Flaschen
2
@MattNorris Você não precisa de um plugin para isso, mas a resposta correta é: window.location.host + window.location.pathname No seu caso, será "www.youtube.com/watch"
nktssh
68

Para responder à minha própria pergunta 4 anos depois, depois de ter aprendido muito. Especialmente que você não deve usar o jQuery para tudo. Eu criei um módulo simples que pode analisar / stringify uma string de consulta. Isso facilita a modificação da string de consulta.

Você pode usar a string de consulta da seguinte maneira:

// 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);
Sindre Sorhus
fonte
1
Uau, essa é uma solução brilhantemente simples. Obrigado!
#
Isso funciona como um campeão! Obrigado Sindre 🏆🏆🏆 (Tudo que você precisa fazer é minify "query-string / index.js" e colá-lo no fundo de seus js)
Ronnie Royston
1
Ter uma biblioteca extra apenas para que parece ser um pouco mais ...
The Godfather
63

Pequena solução rápida em js puro, sem necessidade de plugins:

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

Chame assim:

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

Ou, se você deseja permanecer na mesma página e substituir vários parâmetros:

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

editar, graças Lucas: Para remover o parâmetro inteiramente, passar falseou nullpara o valor: replaceQueryParam('rows', false, params). Como 0 também é falso , especifique '0'.

Bronson
fonte
2
Também para remover um parâmetro utilizado a partir da saída fazer isso: str = replaceQueryParam ( 'oldparam', falsa, str) - basicamente colocar um valor Tipo de falsa
Luke Wenke
1
tem problema, duplicação meu parâmetro para nenhuma boa razão, confira esta solução semelhante stackoverflow.com/a/20420424/3160597
azerafati
@ Bludream Esse código trabalha em produção há anos. Ainda não o vi duplicar um parâmetro. Você pode postar uma reprodução ou alguma informação mais construtiva?
18715
@ Bludream Entendo agora, é o script ao qual você vinculou que estava adicionando parâmetros duplicados. :)
Bronson
1
@dVyper correto, um valor falso remove completamente o parâmetro. Use o texto '0' em vez do número inteiro.
bronson
62

Ben Alman tem uma boa jquery querystring / url plug-in aqui que permite que você manipule a querystring facilmente.

Como pedido -

Vá para a página de teste aqui

No firebug, digite o seguinte no console

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

Ele retornará a seguinte string de URL alterada

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

Observe que o valor de uma querystring para a mudou de X para 3 e adicionou o novo valor.

Você pode usar a nova string de URL da maneira que desejar, por exemplo, usando document.location = newUrl ou alterar um link de âncora etc.

quadrado vermelho
fonte
4
Não é jQuery.param.querystring em vez de jQuery.queryString?
quer
12
TypeError: jQuery.param.querystring is not a function
TMS
1
Para avoir 'TypeError' deve ser: jQuery.queryString (window.location.href, 'a = 3 & newValue = 100')
code-gijoe
2
você deveria ligar jQuery.param.querystring. Eu acho que eles refatoraram a biblioteca.
Will Wu
Nenhuma dessas funções existe mais. Você deseja atualizar window.location.search manualmente. Fica mais difícil se você não deseja que a página seja redesenhada, pois isso causará uma alteração na página.
monokrome
38

Uma abordagem moderna para isso é usar URLSearchParams baseado em padrão nativo . É suportado por todos os principais navegadores, exceto pelo IE, onde estão disponíveis polyfills

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.
Alister
fonte
1
Seria muito bom ... mas não é como o IE não o suporta, e usar polyfills para uma coisa tão pequena está totalmente fora de questão.
Forsberg
1
isso também urlencodes o paramsString original na íntegra, por isso os olhares resultado como site.fwx%3Fposition=1&archiveid=5000&columns=5&rows=10&sorting=ModifiedTimeAsco que é confuso, porque não é o que você teria construído se você fez isso manualmente ...
Ben Wheeler
1
Seria bom ver um exemplo de como usá-lo. Quero dizer, como obter seqüência de parâmetros da página atual e como configurá-lo depois
The Godfather
27

você pode fazer isso via JS normal também

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;
Posto
fonte
Agradável! Eu peguei isso e modifiquei em uma função. Você envia o URL atual, o nome do parâmetro que está procurando, o novo valor e um bool informando se você deseja adicionar o parâmetro à string de consulta se eu não o encontrar atualmente. A função retorna o URL modificado.
Gromer
Gormer, você deve compartilhar essa função com outros :)
Adil Malik
Trecho impressionante. Eu também a transformei em uma função para meu próprio caso de uso. Obrigado por compartilhar! +1
robabby
18

Esta é a maneira moderna de alterar os parâmetros de URL:

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);
  }
}
TjerkW
fonte
2
Atualmente, esta solução não é suportada no Internet Explorer 11: caniuse.com/#search=URLSearchParams
WoIIe
A mesma resposta foi respondida meio ano antes de você por @Alister
FantomX1
10

Uma alternativa viável à manipulação de String seria configurar um html forme apenas modificar o valor do rowselemento?

Então, com htmlisso é algo como

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

Com o seguinte JavaScript para enviar o formulário

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

Provavelmente não é adequado para todas as situações, mas pode ser mais agradável do que analisar a string da URL.

Harry Lime
fonte
Essa é inteligente.
Icarito 15/0318
7

Você pode usar esta minha biblioteca para fazer o trabalho: 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);
Mikhus
fonte
4

Solução 2020 : define a variável ou remove-a se você passar nullou undefinedpara o valor.

var setSearchParam = function(key, value) {
    if (!window.history.pushState) {
        return;
    }

    if (!key) {
        return;
    }

    var url = new URL(window.location.href);
    var params = new window.URLSearchParams(window.location.search);
    if (value === undefined || value === null) {
        params.delete(key);
    } else {
        params.set(key, value);
    }

    url.search = params;
    url = url.toString();
    window.history.replaceState({url: url}, null, url);
}
Alper Ebicoglu
fonte
Observe que URLSearchParamsnão funciona nas versões mais recentes de todos os principais navegadores (2020)
Oliver Schimmer
É suportado em todos os principais navegadores, exceto o IE11: caniuse.com/#search=URLSearchParams
Luis Paulo Lohmann
Mesmo que tenha começado a ser suportado, a mesma resposta com URLSearchParams foi respondida nesta pergunta pelo menos 3 vezes, já em 15 de janeiro de 17 às 15:24, em 14 de junho de 18 às 15:54 e em 1 de março de 19 às 12:46, como se ninguém estivesse lendo respostas antes de postar
FantomX1
todas as postagens têm problemas menores que precisam ser resolvidos. então deixe os usuários votar e escolher o melhor.
Alper Ebicoglu
3

Eu escrevi uma pequena função auxiliar que funciona com qualquer seleção. Tudo o que você precisa fazer é adicionar a classe "redirectOnChange" a qualquer elemento de seleção, e isso fará com que a página seja recarregada com um parâmetro de querystring novo / alterado, igual ao ID e ao valor da seleção, por exemplo:

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

O exemplo acima adicionaria "? MyValue = 222" ou "? MyValue = 333" (ou usar "&" se existirem outros parâmetros) e recarregar a página.

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);
    });
});
Paul Grimshaw
fonte
De longe, a melhor solução nesta página
ed209 14/10
2

Aqui, peguei a resposta de Adil Malik e corrigi os três problemas que identifiquei com ela.

/**
 * 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;
  }
}
Jonathan Aquino
fonte
1

Aqui está o que eu faço. Usando minha função editParams (), você pode adicionar, remover ou alterar qualquer parâmetro e, em seguida, usar a função replaceState () incorporada para atualizar a 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;
}
Bobb Fwed
fonte
Um voto negativo sem um comentário? O que há de errado com o código? Funciona fantástico para muitas situações.
Bobb Fwed
1

Minha solução:

const setParams = (data) => {
    if (typeof data !== 'undefined' && typeof data !== 'object') {
        return
    }

    let url = new URL(window.location.href)
    const params = new URLSearchParams(url.search)

    for (const key of Object.keys(data)) {
        if (data[key] == 0) {
            params.delete(key)
        } else {
            params.set(key, data[key])
        }
    }

    url.search = params
    url = url.toString()
    window.history.replaceState({ url: url }, null, url)
}

Em seguida, basta chamar "setParams" e passar um objeto com os dados que você deseja definir.

Exemplo:

$('select').on('change', e => {
    const $this = $(e.currentTarget)
    setParams({ $this.attr('name'): $this.val() })
})

No meu caso, eu tive que atualizar uma entrada de seleção html quando ela muda e se o valor for "0", remova o parâmetro. Você pode editar a função e remover o parâmetro do URL se a chave do objeto também for "nula".

Espero que isso ajude todos

Benjamin
fonte
já existem duas respostas iguais para URLSearchParams antes de você, como se ninguém realmente lesse respostas. Postado em respondidas Jan 15 '17 às 15:24, respondidas Jun 14 '18 às 15:54
FantomX1
0

Outra variação na resposta de Sujoy. Apenas alterei os nomes das variáveis ​​e adicionamos um wrapper de namespace:

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

O uso é agora:

var changedUrl = MyNamespace.Uri.SetQueryStringParameter(originalUrl, "CarType", "Ford");
Appetere
fonte
0

Eu também escrevi uma biblioteca para obter e definir parâmetros de consulta de URL em JavaScript .

Aqui está um exemplo de seu uso.

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

Obtenha parâmetros de consulta como um objeto, por chave ou adicione / altere / remova.

// 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
rb-
fonte
-1

Eu sei que esta é uma pergunta antiga. Eu aprimorei a função acima para adicionar ou atualizar parâmetros de consulta. Ainda é apenas uma solução JS pura.

                      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 : '');
                    }
user3799810
fonte
-1

minha função de suporte removendo 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(/\&$/, ''));
    }
lossy11
fonte
-1

Acabei de escrever um módulo simples para lidar com a leitura e atualização dos parâmetros de consulta de URL atuais.

Exemplo de uso:

import UrlParams from './UrlParams'

UrlParams.remove('foo') //removes all occurences of foo=?
UrlParams.set('foo', 'bar') //set all occurences of foo equal to bar
UrlParams.add('foo', 'bar2') //add bar2 to foo result: foo=bar&foo=bar2
UrlParams.get('foo') //returns bar
UrlParams.get('foo', true) //returns [bar, bar2]

Aqui está o meu código chamado UrlParams. (Js / ts):

class UrlParams {

    /**
     * Get params from current url
     * 
     * @returns URLSearchParams
     */
    static getParams(){
        let url = new URL(window.location.href)
        return new URLSearchParams(url.search.slice(1))
    }

    /**
     * Update current url with params
     * 
     * @param params URLSearchParams
     */
    static update(params){
        if(`${params}`){
            window.history.replaceState({}, '', `${location.pathname}?${params}`)
        } else {
            window.history.replaceState({}, '', `${location.pathname}`)
        }
    }

    /**
     * Remove key from url query
     * 
     * @param param string
     */
    static remove(param){
        let params = this.getParams()
        if(params.has(param)){
            params.delete(param)
            this.update(params)
        }
    }

    /**
     * Add key value pair to current url
     * 
     * @param key string
     * @param value string
     */
    static add(key, value){
        let params = this.getParams()
        params.append(key, value)
        this.update(params)
    }

    /**
     * Get value or values of key
     * 
     * @param param string
     * @param all string | string[]
     */
    static get(param, all=false){
        let params = this.getParams()
        if(all){
            return params.getAll(param)
        }
        return params.get(param)
    }

    /**
     * Set value of query param
     * 
     * @param key string
     * @param value string
     */
    static set(key, value){
        let params = this.getParams()
        params.set(key, value)
        this.update(params)
    }

}
export default UrlParams
export { UrlParams }
Dieter Gribnitz
fonte
Já existem 4 respostas iguais às mencionadas, respondidas em 15 de janeiro de 17 às 15:24, respondidas em 14 de junho de 18 às 15:54, respondidas em 1 de março de 19 às 12:46 e respondidas em 14 de junho às 7: 20, como se ninguém realmente tivesse lido as respostas antes de postar
FantomX1
-2
     // usage: clear ; cd src/js/node/js-unit-tests/01-set-url-param ; npm test ; cd -
     // prereqs: , nodejs , mocha
     // URI = scheme:[//authority]path[?paramName1=paramValue1&paramName2=paramValue2][#fragment]
     // call by: uri = uri.setUriParam("as","md")
     String.prototype.setUriParam = function (paramName, paramValue) {
        var uri = this
        var fragment = ( uri.indexOf('#') === -1 ) ? '' : uri.split('#')[1]
        uri = ( uri.indexOf('#') === -1 ) ? uri : uri.split('#')[0]
        if ( uri.indexOf("?") === -1 ) { uri = uri + '?&' }
        uri = uri.replace ( '?' + paramName , '?&' + paramName)
        var toRepl = (paramValue != null) ? ('$1' + paramValue) : ''
        var toSrch = new RegExp('([&]' + paramName + '=)(([^&#]*)?)')
        uri = uri.replace(toSrch,toRepl)
        if (uri.indexOf(paramName + '=') === -1 && toRepl != '' ) {
           var ampersandMayBe = uri.endsWith('&') ? '' : '&'
           uri = uri + ampersandMayBe + paramName + "=" + String(paramValue)
        }
        uri = ( fragment.length == 0 ) ? uri : (uri+"#"+fragment) //may-be re-add the fragment
        return uri
     }

     var assert = require('assert');
     describe('replacing url param value', function () {

        // scheme://authority/path[?p1=v1&p2=v2#fragment
        // a clean url
        it('http://org.com/path -> http://org.com/path?&prm=tgt_v', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=10'
           var uriActual = uri.setUriParam("bid",10)
           assert.equal(uriActual, uriExpected);
        });

        // has the url param existing after the ? with num value
        it('http://org.com/path?prm=src_v -> http://org.com/path?&prm=tgt_v', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?bid=57'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=10'
           var uriActual = uri.setUriParam("bid",10)
           assert.equal(uriActual, uriExpected);
        });

        // has the url param existing after the ? but string value
        it('http://org.com/path?prm=src_v -> http://org.com/path?&prm=tgt_v', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?bid=boo-bar'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=boo-bar-baz'
           var uriActual = uri.setUriParam("bid","boo-bar-baz")
           assert.equal(uriActual, uriExpected);
        });

        // has the url param existing after the ?& but string value
        it('http://org.com/path?&prm=src_v -> http://org.com/path?&prm=tgt_v', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=5'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=10'
           var uriActual = uri.setUriParam("bid",10)
           assert.equal(uriActual, uriExpected);
        });

        // has the url param existing after the ? with other param
        it('http://org.com/path?prm=src_v&other_p=other_v -> http://org.com/path?&prm=tgt_v&other_p=other_v', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?bid=5&other_p=other_v'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=10&other_p=other_v'
           var uriActual = uri.setUriParam("bid",10)
           assert.equal(uriActual, uriExpected);
        });

        // has the url param existing after the ?& with other param
        it('http://org.com/path?&prm=src_v&other_p=other_v -> http://org.com/path?&prm=tgt_v&other_p=other_v', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=5&other_p&other_v'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=10&other_p&other_v'
           var uriActual = uri.setUriParam("bid",10)
           assert.equal(uriActual, uriExpected);
        });

        // has the url param existing after the ? with other param with fragment
        it('http://org.com/path?prm=src_v&other_p=other_v#f -> http://org.com/path?&prm=tgt_v&other_p=other_v#f', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?bid=5&other_p=other_v#f'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=10&other_p=other_v#f'
           var uriActual = uri.setUriParam("bid",10)
           assert.equal(uriActual, uriExpected);
        });

        // has the url param existing after the ?& with other param with fragment
        it('http://org.com/path?&prm=src_v&other_p=other_v#f -> http://org.com/path?&prm=tgt_v&other_p=other_v#f', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=5&other_p&other_v#f'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=10&other_p&other_v#f'
           var uriActual = uri.setUriParam("bid",10)
           assert.equal(uriActual, uriExpected);
        });

        // remove the param-name , param-value pair
        it('http://org.com/path?prm=src_v&other_p=other_v#f -> http://org.com/path?&prm=tgt_v&other_p=other_v#f', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?bid=5&other_p=other_v#f'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&other_p=other_v#f'
           var uriActual = uri.setUriParam("bid",null)
           assert.equal(uriActual, uriExpected);
        });

        // remove the param-name , param-value pair
        it('http://org.com/path?&prm=src_v&other_p=other_v#f -> http://org.com/path?&prm=tgt_v&other_p=other_v#f', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=5&other_p=other_v#f'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&other_p=other_v#f'
           var uriActual = uri.setUriParam("bid",null)
           assert.equal(uriActual, uriExpected);
        });

        // add a new param name , param value pair
        it('http://org.com/path?prm=src_v&other_p=other_v#f -> http://org.com/path?&prm=tgt_v&other_p=other_v#f', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?&other_p=other_v#f'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&other_p=other_v&bid=foo-bar#f'
           var uriActual = uri.setUriParam("bid","foo-bar")
           assert.equal(uriActual, uriExpected);
        });

     });
Yordan Georgiev
fonte