Adicionando um parâmetro ao URL com JavaScript


276

Em um aplicativo Web que utiliza chamadas AJAX, preciso enviar uma solicitação, mas adicionar um parâmetro ao final da URL, por exemplo:

URL original:

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

URL resultante:

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

Procurando por uma função JavaScript que analise a URL observando cada parâmetro e adicione o novo parâmetro ou atualize o valor, se já existir.


Você pesquisou analisadores de url em javascript ? Você pode criar o seu próprio, dividindo-se em cada caractere &, mas provavelmente é mais fácil usar o código existente.
CSL

1
Tive um cenário semelhante uma vez e achei este artigo de Peter Bromberg muito útil:
Cerebrus

2
window.history.pushState ('page2', 'Title', document.location + '/ page2.php'); vai fazer o seu trabalho sem o carregamento da página
Rutunj sheladiya

1
Esta pergunta tem melhores respostas aqui stackoverflow.com/questions/6953944/…
rkb

inacreditável este nativo is not nesta língua pobre que JS é ....
bohr

Respostas:


192

Uma implementação básica que você precisará adaptar seria mais ou menos assim:

function insertParam(key, value) {
    key = encodeURIComponent(key);
    value = encodeURIComponent(value);

    // kvp looks like ['key1=value1', 'key2=value2', ...]
    var kvp = document.location.search.substr(1).split('&');
    let i=0;

    for(; i<kvp.length; i++){
        if (kvp[i].startsWith(key + '=')) {
            let pair = kvp[i].split('=');
            pair[1] = value;
            kvp[i] = pair.join('=');
            break;
        }
    }

    if(i >= kvp.length){
        kvp[kvp.length] = [key,value].join('=');
    }

    // can return this or...
    let params = kvp.join('&');

    // reload page with new params
    document.location.search = params;
}

Isso é aproximadamente duas vezes mais rápido que uma solução baseada em regex ou pesquisa, mas isso depende completamente do tamanho da string de consulta e do índice de qualquer correspondência


o método regex lento com o qual comparou comparativamente para fins de conclusão (aproximadamente + 150% mais lento)

function insertParam2(key,value)
{
    key = encodeURIComponent(key); value = encodeURIComponent(value);

    var s = document.location.search;
    var kvp = key+"="+value;

    var r = new RegExp("(&|\\?)"+key+"=[^\&]*");

    s = s.replace(r,"$1"+kvp);

    if(!RegExp.$1) {s += (s.length>0 ? '&' : '?') + kvp;};

    //again, do what you will here
    document.location.search = s;
}

2
obrigado novamente. veja lessanvaezi.com/wp-content/uploads/2009/01/test.html para uma comparação básica dos métodos
Lessan Vaezi

16
Usar escape () para escapar dos parâmetros da URL está errado. Ele quebra para valores com "+" neles. Você deve usar encodeURIComponent. Discussão completa: xkr.us/articles/javascript/encode-compare
Antonin Hildebrand

4
Eu estou chamando essa função e a página está recarregando em loop infinito. Por favor ajude!
sumit 24/07

6
quando há parâmetros já estão no url você recebe um e param = valor?
Roy Toledo

9
Você não deveria estar usando encodeURIComponente não encodeURI? Caso contrário, qualquer caractere como =, &em seu nome ou valor, corromperá o URI.
Adrian Pronk

271

Você pode usar um destes:

Exemplo:

var url = new URL("http://foo.bar/?x=1&y=2");

// If your expected result is "http://foo.bar/?x=1&y=2&x=42"
url.searchParams.append('x', 42);

// If your expected result is "http://foo.bar/?x=42&y=2"
url.searchParams.set('x', 42);

2
Eu gostaria de adicionar um parâmetro de consulta sem um valor, por exemplo, adicionando XMLa http://foo.bar/?x=1&y=2para que o resultado final seja http://foo.bar/?x=1&y=2&XML. Isso é possível? Eu tentei url.searchParams.set('XML');, url.searchParams.set('XML', null);e url.searchParams.set('XML', undefined);- mas nenhum funcionou no Chrome 63 .
Abdull

2
Obrigado! Pena que ainda não é suportado pelo iOS. developer.mozilla.org/pt-BR/docs/Web/API/URLSearchParams
kanji

27
Pena que o IE não suporta.
Spedy # 20/18

3
O iOS agora suportam URLSearchParams (desde 9 dias após @ o comentário de kanji)
MJeffryes

8
Boas notícias @MJeffryes! Ainda não é suportado pelo IE e Netscape.
Vianney Bajart 28/03

64

Obrigado a todos por sua contribuição. Eu usei o código annakata e modifiquei para incluir também o caso em que não há nenhuma string de consulta no URL. Espero que isso ajude.

function insertParam(key, value) {
        key = escape(key); value = escape(value);

        var kvp = document.location.search.substr(1).split('&');
        if (kvp == '') {
            document.location.search = '?' + key + '=' + value;
        }
        else {

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

            //this will reload the page, it's likely better to store this until finished
            document.location.search = kvp.join('&');
        }
    }

3
Seria melhor mudar de escape(key)e escape(value)para encodeURIComponentfuncionar.
Kolobok

5
isso deve realmente verificar if (kvp.length==1 && kvp[0]="")?
Charles L.

@CharlesL. melhor éif (document.location.search)
Lyubimov Roman

58

Esta é uma solução muito simples. Não controla a existência de parâmetros e não altera o valor existente. Ele adiciona seu parâmetro ao final, para que você possa obter o valor mais recente no seu código de back-end.

function addParameterToURL(param){
    _url = location.href;
    _url += (_url.split('?')[1] ? '&':'?') + param;
    return _url;
}

6
você também deve responder por "#" no url .. aqui vai uma poça código:url = (url.indexOf("?") != -1 ? url.split("?")[0]+"?"+part+"&"+url.split("?")[1] : (url.indexOf("#") != -1 ? url.split("#")[0]+"?"+part+"#"+ url.split("#")[1] : url+'?'+part));
kanzure

2
@kanzure essa coisa parece ruim como o inferno, mas é exatamente o que eu queria. Obrigado.
Chad von Nau

por que dividir o URL para verificar a existência de um único caractere? Também não se esqueça de codificação ... algo mais parecidofunction appendQs(url, key, value) { return url + (url.indexOf('?') >= 0 ? "&" : '?') + encodeURIComponent(key) + "=" + encodeURIComponent(value); };
drzaus

1
Consertá-lo. Esta função não verifica se o parâmetro já foi fornecido. Eu testei isso e consegui https://localhost/preview/inventory.html?sortci=priceASC&sortci=priceASC&sortci=stitle.
Jay

@ Jay, por que ele precisa de conserto? Verifique suas suposições. Parâmetros de cadeia de consulta duplicados são legais, o mesmo que campos de formulário duplicados. É assim que as listas de caixas de seleção são implementadas. Em HTML e elas serão transmitidas via string de consulta se o método form = get.
stephen

34

Aqui está uma versão bastante simplificada, fazendo trocas por legibilidade e menos linhas de código em vez de desempenho micro-otimizado (e estamos falando de uma diferença de alguns milissegundos, realisticamente ... devido à natureza disso (operando na localização do documento atual) ), provavelmente será executado uma vez em uma página).

/**
* Add a URL parameter (or changing it if it already exists)
* @param {search} string  this is typically document.location.search
* @param {key}    string  the key to set
* @param {val}    string  value 
*/
var addUrlParam = function(search, key, val){
  var newParam = key + '=' + val,
      params = '?' + newParam;

  // If the "search" string exists, then build params from it
  if (search) {
    // Try to replace an existance instance
    params = search.replace(new RegExp('([?&])' + key + '[^&]*'), '$1' + newParam);

    // If nothing was replaced, then add the new param to the end
    if (params === search) {
      params += '&' + newParam;
    }
  }

  return params;
};

Você usaria isso assim:

document.location.pathname + addUrlParam(document.location.search, 'foo', 'bar');

1
+1 Eu gosto de como você pode especificar algo diferente do que document.location.search
Muhd

1
+1 Incrível, eu concordo que a legibilidade é mais importante do que a micro-otimização neste caso e estou feliz por ver alguém ter adotado essa abordagem. @ Muhd ​​Talvez tenha sido um bug no mecanismo JS quando você escreveu esse comentário, mas eu apenas testei '$ 1' nesse contexto e funciona bem.
JMTyler #

Muito obrigado pela solução, embora eu também fique paralisado se desejar substituir um valor e já houver um parâmetro lá. Em vez disso, ele escreve $ 1
Codebryo

2
Garrett: Você poderia corrigir sua resposta para substituir os parâmetros existentes corretamente? É apenas uma questão de substituir [\?&]com ([\?&])no RegExp (eu tinha acabado de editar-lo eu mesmo, mas eu não tenho certeza se a política comunitária permite corrigir erros em respostas).
opyh

Isso não está funcionando com o URL como " domain.tld ", seu add "&" em vez de "?"
user706420

20

/**
* Add a URL parameter 
* @param {string} url 
* @param {string} param the key to set
* @param {string} value 
*/
var addParam = function(url, param, value) {
   param = encodeURIComponent(param);
   var a = document.createElement('a');
   param += (value ? "=" + encodeURIComponent(value) : ""); 
   a.href = url;
   a.search += (a.search ? "&" : "") + param;
   return a.href;
}

/**
* Add a URL parameter (or modify if already exists)
* @param {string} url 
* @param {string} param the key to set
* @param {string} value 
*/
var addOrReplaceParam = function(url, param, value) {
   param = encodeURIComponent(param);
   var r = "([&?]|&amp;)" + param + "\\b(?:=(?:[^&#]*))*";
   var a = document.createElement('a');
   var regex = new RegExp(r);
   var str = param + (value ? "=" + encodeURIComponent(value) : ""); 
   a.href = url;
   var q = a.search.replace(regex, "$1"+str);
   if (q === a.search) {
      a.search += (a.search ? "&" : "") + str;
   } else {
      a.search = q;
   }
   return a.href;
}

url = "http://www.example.com#hashme";
newurl = addParam(url, "ciao", "1");
alert(newurl);

E observe que os parâmetros devem ser codificados antes de serem anexados na string de consulta.

http://jsfiddle.net/48z7z4kx/


Pequena perda de memória - você deseja remover o elemento âncora que foi adicionado ao documento antes de retornar.
cânhamo

@ Freedev, Não, não tenho certeza. ;) Estou tendo dificuldade em encontrar uma fonte autorizada, mas as evidências sugerem que você está correto. Como o elemento criado nunca é anexado ao DOM, ele deve ser limpo assim que a variável ficar fora do escopo. A API do DOM não é particularmente bem projetada quando se trata de efeitos colaterais, por isso sou muito cauteloso.
quer

Esta solução adiciona uma barra final aos URLs que não possuem parâmetros de caminho e reordena, que são alterações desnecessárias e possivelmente indesejáveis. Também anexa, em vez de substituir parâmetros existentes que não têm valor (por exemplo http://abc.def/?a&b&b).
precisa

@AdamLeggett Obrigado por apontar o erro que ocorre quando um parâmetro de solicitação não tem valor, eu apenas corrigi minha resposta. Os comportamentos estranhos restantes de que você está falando, se você estiver certo, são gerados pelo objeto âncora HTML, que geralmente é um componente padrão do navegador. Sugiro verificar novamente, porque é muito improvável que um navegador adicione comportamentos desnecessários ou indesejáveis.
freedev

1
O objetivo da função addParam é de fato adicionar várias vezes um parâmetro e talvez você deva saber que pode passar o mesmo parâmetro mesmo com o mesmo valor várias vezes. stackoverflow.com/questions/24059773/…
freedev

20
const urlParams = new URLSearchParams(window.location.search);

urlParams.set('order', 'date');

window.location.search = urlParams;

.set primeiro agrument é a chave, o segundo é o valor.


1
Amo a simplicidade desta e que usa métodos navegador nativo
Juan Solano

2
Esta é a resposta correta e deve ser a mais votada. Esta nova API é definitiva para o processamento de URL
Anthony

19

Eu tenho uma 'classe' que faz isso e aqui está:

function QS(){
    this.qs = {};
    var s = location.search.replace( /^\?|#.*$/g, '' );
    if( s ) {
        var qsParts = s.split('&');
        var i, nv;
        for (i = 0; i < qsParts.length; i++) {
            nv = qsParts[i].split('=');
            this.qs[nv[0]] = nv[1];
        }
    }
}

QS.prototype.add = function( name, value ) {
    if( arguments.length == 1 && arguments[0].constructor == Object ) {
        this.addMany( arguments[0] );
        return;
    }
    this.qs[name] = value;
}

QS.prototype.addMany = function( newValues ) {
    for( nv in newValues ) {
        this.qs[nv] = newValues[nv];
    }
}

QS.prototype.remove = function( name ) {
    if( arguments.length == 1 && arguments[0].constructor == Array ) {
        this.removeMany( arguments[0] );
        return;
    }
    delete this.qs[name];
}

QS.prototype.removeMany = function( deleteNames ) {
    var i;
    for( i = 0; i < deleteNames.length; i++ ) {
        delete this.qs[deleteNames[i]];
    }
}

QS.prototype.getQueryString = function() {
    var nv, q = [];
    for( nv in this.qs ) {
        q[q.length] = nv+'='+this.qs[nv];
    }
    return q.join( '&' );
}

QS.prototype.toString = QS.prototype.getQueryString;

//examples
//instantiation
var qs = new QS;
alert( qs );

//add a sinle name/value
qs.add( 'new', 'true' );
alert( qs );

//add multiple key/values
qs.add( { x: 'X', y: 'Y' } );
alert( qs );

//remove single key
qs.remove( 'new' )
alert( qs );

//remove multiple keys
qs.remove( ['x', 'bogus'] )
alert( qs );

Eu substituí o método toString, portanto não há necessidade de chamar QS :: getQueryString, você pode usar QS :: toString ou, como já fiz nos exemplos, basta confiar no objeto sendo coagido em uma string.


8

Se você tem uma string com url que deseja decorar com um parâmetro, tente o seguinte:

urlstring += ( urlstring.match( /[\?]/g ) ? '&' : '?' ) + 'param=value';

Isso significa isso ? será o prefixo do parâmetro, mas se você já possui ? em urlstring, que & será o prefixo.

Eu recomendaria também fazer encodeURI( paramvariable )se você não codificou o parâmetro, mas está dentro de umparamvariable ; ou se você tiver personagens engraçados.

Consulte a codificação de URL javascript para usar a encodeURIfunção.


7

Esta é uma maneira simples de adicionar um parâmetro de consulta:

const query = new URLSearchParams(window.location.search);
query.append("enabled", "true");

E é isso mais aqui .

Observe as especificações de suporte .


4
Parece que isso não é suportado em nenhuma versão do Internet Explorer
MAXE 6/17

Ideal para celular. Quando o Internet Explorer aparecer no meu dispositivo móvel, eu o jogarei fora. :-)
stillatmylinux 29/09

@MAXE você está certo O IE / EDGE não suporta muito. Com suporte em
T04435 02/10

6

Confira https://github.com/derek-watson/jsUri

Manipulação de URL e consulta em javascript.

Este projeto incorpora a excelente biblioteca de expressões regulares parseUri de Steven Levithan. Você pode analisar com segurança URLs de todas as formas e tamanhos, por mais inválidos ou hediondos.


404 - O URL solicitado / p / jsuri / não foi encontrado neste servidor. Isso é tudo que sabemos.
precisa saber é o seguinte

1
Parece que foi movido. Eu atualizei o URL. Boa sorte!
Charlie Liang Yuan

Inclua os detalhes relevantes na sua resposta, não apenas um link.
jhpratt GOFUNDME relicenciando

6

Às vezes vemos ?no URL final, encontrei algumas soluções que geram resultados como file.php?&foo=bar. Eu vim com minha própria solução funcionar perfeitamente como eu quero!

location.origin + location.pathname + location.search + (location.search=='' ? '?' : '&') + 'lang=ar'

Nota: location.origin não funciona no IE, aqui está sua correção .


6

A função a seguir ajudará você a adicionar, atualizar e excluir parâmetros para ou do URL.

// example1and

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

// exemplo2

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

// exemplo3

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

// example4

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

Aqui está a função.

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

5

Esta foi minha própria tentativa, mas usarei a resposta de annakata, pois parece muito mais limpa:

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

Além disso, eu encontrei esse plugin jQuery em outra postagem no stackoverflow e, se precisar de mais flexibilidade, poderá usá-lo: http://plugins.jquery.com/project/query-object

Eu acho que o código seria (não testei):

return $.query.parse(sourceUrl).set(parameterName, parameterValue).toString();

Obrigado por compartilhar seu código, Lessan. Eu tenho usado isso e funcionou muito bem! Fiz upload de uma essência da minha própria versão, editada para ser um pouco mais sucinta e passar na validação JSHint. gist.github.com/jonathanconway/02a183920506acd9890a
Jonathan

3

Adicionando à @ Vianney's Answer https://stackoverflow.com/a/44160941/6609678

Podemos importar o módulo de URL embutido no nó da seguinte maneira

const { URL } = require('url');

Exemplo:

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'

Links Úteis:

https://developer.mozilla.org/en-US/docs/Web/API/URL https://developer.mozilla.org/en/docs/Web/API/URLSearchParams


3

Tente isso.

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

url.searchParamsé a lista de parâmetros pré-inicializados para esse URLobjeto.
amphetamachine

2

Eu gosto da resposta de Mehmet Fatih Yıldız, mesmo que ele não tenha respondido a toda a pergunta.

Na mesma linha que sua resposta, eu uso este código:

"Não controla a existência de parâmetros e não altera o valor existente. Adiciona seu parâmetro ao final"

  /** add a parameter at the end of the URL. Manage '?'/'&', but not the existing parameters.
   *  does escape the value (but not the key)
   */
  function addParameterToURL(_url,_key,_value){
      var param = _key+'='+escape(_value);

      var sep = '&';
      if (_url.indexOf('?') < 0) {
        sep = '?';
      } else {
        var lastChar=_url.slice(-1);
        if (lastChar == '&') sep='';
        if (lastChar == '?') sep='';
      }
      _url += sep + param;

      return _url;
  }

e o testador:

  /*
  function addParameterToURL_TESTER_sub(_url,key,value){
    //log(_url);
    log(addParameterToURL(_url,key,value));
  }

  function addParameterToURL_TESTER(){
    log('-------------------');
    var _url ='www.google.com';
    addParameterToURL_TESTER_sub(_url,'key','value');
    addParameterToURL_TESTER_sub(_url,'key','Text Value');
    _url ='www.google.com?';
    addParameterToURL_TESTER_sub(_url,'key','value');
    _url ='www.google.com?A=B';
    addParameterToURL_TESTER_sub(_url,'key','value');
    _url ='www.google.com?A=B&';
    addParameterToURL_TESTER_sub(_url,'key','value');
    _url ='www.google.com?A=1&B=2';
    addParameterToURL_TESTER_sub(_url,'key','value');

  }//*/


2

É isso que eu uso quando se trata de algumas adições ou atualizações básicas de parâmetros de URL no lado do servidor, como Node.js.

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>


2

A solução mais fácil, funciona se você já possui uma tag ou não, e a remove automaticamente para que não continue adicionando tags iguais, divirta-se

function changeURL(tag)
{
if(window.location.href.indexOf("?") > -1) {
    if(window.location.href.indexOf("&"+tag) > -1){

        var url = window.location.href.replace("&"+tag,"")+"&"+tag;
    }
    else
    {
        var url = window.location.href+"&"+tag;
    }
}else{
    if(window.location.href.indexOf("?"+tag) > -1){

        var url = window.location.href.replace("?"+tag,"")+"?"+tag;
    }
    else
    {
        var url = window.location.href+"?"+tag;
    }
}
  window.location = url;
}

ENTÃO

changeURL("i=updated");

2

A resposta de Vianney Bajart está correta; no entanto, o URL funcionará apenas se você tiver o URL completo com porta, host, caminho e consulta:

new URL('http://server/myapp.php?id=10&enabled=true')

E URLSearchParams funcionará apenas se você passar apenas a string de consulta:

new URLSearchParams('?id=10&enabled=true')

Se você tem um URL incompleto ou relativo e não se importa com o URL base, basta dividir ?para obter a string de consulta e ingressar mais tarde, assim:

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'

Não é compatível com o Internet Explorer.


Se você usar var u = new URL(window.location), usp = u.searchParams;, não precisará usar nenhuma divisão de fantasia.
amphetamachine

Embora sua solução funcione para a maioria das coisas, ela alterará o URL se houver um ponto de interrogação no valor de um parâmetro:setUrlParams('https://example.com?foo=thing???&bar=baz', 'baz', 'qux') => "https://example.com?foo=thing&baz=qux???&bar=baz"
amphetamachine

1

Se você estiver mexendo com URLs em links ou em outro lugar, talvez seja necessário levar o hash em consideração também. Aqui está uma solução bastante simples de entender. Provavelmente não é o MAIS RÁPIDO, pois usa um regex ... mas em 99,999% dos casos, a diferença realmente não importa!

function addQueryParam( url, key, val ){
    var parts = url.match(/([^?#]+)(\?[^#]*)?(\#.*)?/);
    var url = parts[1];
    var qs = parts[2] || '';
    var hash = parts[3] || '';

    if ( !qs ) {
        return url + '?' + key + '=' + encodeURIComponent( val ) + hash;
    } else {
        var qs_parts = qs.substr(1).split("&");
        var i;
        for (i=0;i<qs_parts.length;i++) {
            var qs_pair = qs_parts[i].split("=");
            if ( qs_pair[0] == key ){
                qs_parts[ i ] = key + '=' + encodeURIComponent( val );
                break;
            }
        }
        if ( i == qs_parts.length ){
            qs_parts.push( key + '=' + encodeURIComponent( val ) );
        }
        return url + '?' + qs_parts.join('&') + hash;
    }
}

Não sei por que alguém lhe deu um voto negativo. Essa é uma das soluções mais confiáveis, embora seja muito mais código do que o necessário.
precisa

1

A solução mais simples que consigo pensar é esse método, que retornará o URI modificado. Sinto que a maioria de vocês está trabalhando demais.

function setParam(uri, key, val) {
    return uri
        .replace(new RegExp("([?&]"+key+"(?=[=&#]|$)[^#&]*|(?=#|$))"), "&"+key+"="+encodeURIComponent(val))
        .replace(/^([^?&]+)&/, "$1?");
}

0

Ok, aqui eu comparo duas funções, uma feita por mim (regExp) e outra feita por (annakata).

Dividir matriz:

function insertParam(key, value)
{
    key = escape(key); value = escape(value);

    var kvp = document.location.search.substr(1).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('=');}

    //this will reload the page, it's likely better to store this until finished
    return "&"+kvp.join('&'); 
}

Método Regexp:

function addParameter(param, value)
{
    var regexp = new RegExp("(\\?|\\&)" + param + "\\=([^\\&]*)(\\&|$)");
    if (regexp.test(document.location.search)) 
        return (document.location.search.toString().replace(regexp, function(a, b, c, d)
        {
                return (b + param + "=" + value + d);
        }));
    else 
        return document.location.search+ param + "=" + value;
}

Caso de teste:

time1=(new Date).getTime();
for (var i=0;i<10000;i++)
{
addParameter("test","test");
}
time2=(new Date).getTime();
for (var i=0;i<10000;i++)
{
insertParam("test","test");
}

time3=(new Date).getTime();

console.log((time2-time1)+" "+(time3-time2));

Parece que mesmo com a solução mais simples (quando o regexp usa apenas teste e não entra na função .replace), ainda é mais lento que a divisão ... Bem. Regexp é meio lento, mas ... uhh ...


como mencionei, isso é comparativamente lento - e fwiw, document.location.search é mais claro
annakata

0

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('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;
}

0

Na melhor das hipóteses, posso dizer que nenhuma das respostas acima aborda o caso em que a string de consulta contém parâmetros que são uma matriz e, portanto, aparecerão mais de uma vez, por exemplo:

http://example.com?sizes[]=a&sizes[]=b

A seguinte função é o que escrevi para atualizar document.location.search. Ele usa uma matriz de matrizes de pares chave / valor como argumento e retornará uma versão revisada da última, com a qual você pode fazer o que quiser. Estou usando assim:

var newParams = [
    ['test','123'],
    ['best','456'],
    ['sizes[]','XXL']
];
var newUrl = document.location.pathname + insertParams(newParams);
history.replaceState('', '', newUrl);

Se o URL atual fosse:

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

Isso te levaria

http://example.com/index.php?test=123&sizes[]=XL&sizes[]=XXL&best=456

Função

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

0

Tente
As expressões regulares, tão lentas, assim:

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

};

Exemplo:

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

0

Com as novas conquistas em JS, veja como se pode adicionar parâmetros de consulta ao URL:

var protocol = window.location.protocol,
    host = '//' + window.location.host,
    path = window.location.pathname,
    query = window.location.search;

var newUrl = protocol + host + path + query + (query ? '&' : '?') + 'param=1';

window.history.pushState({path:newUrl}, '' , newUrl);

Veja também esta possibilidade: Moziila URLSearchParams.append ()


0

Isso funcionará em todos os navegadores modernos.

function insertParam(key,value) {
      if (history.pushState) {
          var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?' +key+'='+value;
          window.history.pushState({path:newurl},'',newurl);
      }
    }

0

Redefinir toda a sequência de consultas

var params = { params1:"val1", params2:"val2" };
let str = jQuery.param(params);

let uri = window.location.href.toString();
if (uri.indexOf("?") > 0)
   uri = uri.substring(0, uri.indexOf("?"));

console.log(uri+"?"+str);
//window.location.href = uri+"?"+str;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.