Como posso adicionar ou atualizar um parâmetro de string de consulta?

364

Com javascript, como posso adicionar um parâmetro de string de consulta ao URL, se não estiver presente ou se estiver presente, atualize o valor atual? Estou usando o jquery para o desenvolvimento do lado do cliente.

amador
fonte
11
Parece que escrevi a função "parseQueryString" em JavaScript cerca de 100 vezes ao longo da minha carreira. Não é díficil. Pontos-chave, String#splitutiliza um segundo parâmetro para divisões máximas. O jQuery maptambém será útil.
Jpsimons
Este post SO também tem muitas soluções stackoverflow.com/questions/1090948/...
Dilip Rajkumar
11
Algumas pessoas estão tomando esta questão para significar "como alterar a URL na barra de endereços" e outros "como alterar qualquer variável URL"
PandaWood
possível duplicação de stackoverflow.com/questions/486896/…
Usuário

Respostas:

468

Eu escrevi a seguinte função que realiza o que eu quero alcançar:

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
  var separator = uri.indexOf('?') !== -1 ? "&" : "?";
  if (uri.match(re)) {
    return uri.replace(re, '$1' + key + "=" + value + '$2');
  }
  else {
    return uri + separator + key + "=" + value;
  }
}
amador
fonte
36
Essa resposta não funciona quando há um hash no URI - as strings de consulta devem ser colocadas antes do hash, caso contrário, elas não são enviadas ao servidor. jsfiddle.net/4yXzR
Greg
20
[?|&]deve ser[?&]
soju
8
Limite o escopo da variável separadora à função local adicionando um varpouco antes da declaração do separador.
Andrea Salicetti
3
Eu acho que você deve adicionar value = encodeURIComponent(value);na primeira linha, caso contrário, as quebras de linha não serão escapadas corretamente.
Felix
18
Isso também resolverá
Niyaz
189

Expandi a solução e a combinei com outra que encontrei para substituir / atualizar / remover os parâmetros da string de consulta com base na entrada do usuário e levando em consideração a âncora dos URLs.

Não fornecer um valor removerá o parâmetro, fornecer um adicionará / atualizará o parâmetro. Se nenhum URL for fornecido, ele será acessado da janela window.location

function UpdateQueryString(key, value, url) {
    if (!url) url = window.location.href;
    var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"),
        hash;

    if (re.test(url)) {
        if (typeof value !== 'undefined' && value !== null) {
            return url.replace(re, '$1' + key + "=" + value + '$2$3');
        } 
        else {
            hash = url.split('#');
            url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
            if (typeof hash[1] !== 'undefined' && hash[1] !== null) {
                url += '#' + hash[1];
            }
            return url;
        }
    }
    else {
        if (typeof value !== 'undefined' && value !== null) {
            var separator = url.indexOf('?') !== -1 ? '&' : '?';
            hash = url.split('#');
            url = hash[0] + separator + key + '=' + value;
            if (typeof hash[1] !== 'undefined' && hash[1] !== null) {
                url += '#' + hash[1];
            }
            return url;
        }
        else {
            return url;
        }
    }
}

Atualizar

Ocorreu um erro ao remover o primeiro parâmetro na string de consulta, refiz o regex e testei para incluir uma correção.

Segunda atualização

Conforme sugerido por @ JarónBarends - Tweak value check para comparar com undefined e null para permitir definir 0 valores

Terceira atualização

Houve um erro no qual remover uma variável de querystring diretamente antes que uma hashtag perdesse o símbolo da hashtag que foi corrigido

Quarta atualização

Obrigado @rooby por apontar uma otimização de regex no primeiro objeto RegExp. Defina regex inicial como ([? &]) Devido a um problema ao usar (\? | &) Encontrado por @YonatanKarni

Quinta Atualização

Removendo a declaração de hash var na instrução if / else

ellemayo
fonte
5
Apenas verificando o 'truthiness' do valuefará isso para remover variáveis da querystring quando definir o seu valor para 0. Assim em vez de if (value) {}você deve usarif (typeOf value !== 'undefined' && value !== null) {}
Jaron Barends
11
No RegExp ([|? &]) Deve ser realmente ([? &])
ROOBY
Engraçado como isso transitadas a solução original - também pode usar (\ |? &)
ellemayo
11
obtendo uma exceção "exceção regular inválida / grupo inválido" na criação de regex no Chrome Versão 31.0.1650.63, resolvida retornando o início para "([? &])"
Yonatan Karni
11
Não que isso importa, exceto para eu ser OCD, mas a variável hashé declarada duas vezes;)
wlingke
117

O utilitário URLSearchParams pode ser útil para isso em combinação com window.location.search. Por exemplo:

if ('URLSearchParams' in window) {
    var searchParams = new URLSearchParams(window.location.search);
    searchParams.set("foo", "bar");
    window.location.search = searchParams.toString();
}

Agora foofoi definido comobar independentemente de já existir ou não.

No entanto, a atribuição acima window.location.searchcausará um carregamento de página; portanto, se isso não for desejável, use a API do histórico da seguinte maneira:

if ('URLSearchParams' in window) {
    var searchParams = new URLSearchParams(window.location.search)
    searchParams.set("foo", "bar");
    var newRelativePathQuery = window.location.pathname + '?' + searchParams.toString();
    history.pushState(null, '', newRelativePathQuery);
}

Agora você não precisa escrever sua própria regex ou lógica para lidar com a possível existência de cadeias de consulta.

No entanto, o suporte ao navegador é ruim, pois atualmente é experimental e só é usado nas versões recentes do Chrome, Firefox, Safari, iOS Safari, Navegador Android, Android Chrome e Opera. Use com um polyfill se você decidir usá-lo.

Atualização: o suporte ao navegador melhorou desde a minha resposta original.

Anthony Manning-Franklin
fonte
polly fill, não é bom, Unable to set property '__URLSearchParams__:0.8503766759030615' of undefined or null reference no ie11 você recebe esse erro. não é um preenchimento de polly se não funcionar como um substituto.
Val
6
Atualização 2019 : o suporte ao navegador agora é bom para a maioria dos navegadores, exceto o IE e alguns pequenos navegadores móveis. O novo pollyfill do ungap cobre facilmente isso: github.com/ungap/url-search-params
Flion
Resposta perfeita, no entanto, ele não é utilizado quando a hashtag está presente no URL. O simples acréscimo de hash até o final do newRelativePathQuerytruque:var newRelativePathQuery = window.location.pathname + '?' + searchParams.toString() + window.location.hash;
kudlohlavec 13/03
43

Com base na resposta do @ amateur (e agora incorporando a correção do comentário @j_walker_dev), mas levando em consideração o comentário sobre as tags hash no URL, eu uso o seguinte:

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");
  if (uri.match(re)) {
    return uri.replace(re, '$1' + key + "=" + value + '$2');
  } else {
    var hash =  '';
    if( uri.indexOf('#') !== -1 ){
        hash = uri.replace(/.*#/, '#');
        uri = uri.replace(/#.*/, '');
    }
    var separator = uri.indexOf('?') !== -1 ? "&" : "?";    
    return uri + separator + key + "=" + value + hash;
  }
}

Editado para corrigir [?|&]no regex, que obviamente deve ser[?&] o indicado nos comentários

Editar: versão alternativa para suportar a remoção de parâmetros de URL também. Eu usei value === undefinedcomo o caminho para indicar a remoção. Pode usar value === falseou mesmo um parâmetro de entrada separado, conforme desejado.

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");
  if( value === undefined ) {
    if (uri.match(re)) {
        return uri.replace(re, '$1$2');
    } else {
        return uri;
    }
  } else {
    if (uri.match(re)) {
        return uri.replace(re, '$1' + key + "=" + value + '$2');
    } else {
    var hash =  '';
    if( uri.indexOf('#') !== -1 ){
        hash = uri.replace(/.*#/, '#');
        uri = uri.replace(/#.*/, '');
    }
    var separator = uri.indexOf('?') !== -1 ? "&" : "?";    
    return uri + separator + key + "=" + value + hash;
  }
  }  
}

Veja em ação em https://jsfiddle.net/bp3tmuxh/1/

Adão
fonte
2
Muito mais limpo. FYI para usuários de ui-roteadores angulares que podem ter "?" no hash também. Mover a var separatorlinha para a direita acima do retorno corrige um erro com "/ app # / cool? Fun = true". Isso escolheria um "&" como separador, mesmo que ainda não haja parâmetros reais de cadeia de caracteres de consulta. Somente clientes.
9135 jjwalker_dev #
3
Como apontado nos comentários de outras respostas, [?|&]deve ser justo [?&](caso contrário, corresponderá |).
Bonger
11
Sim, "([?|&])"não é bom. Corrija isso como quer var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");ou var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");(uma extensão agradável de outras maneiras!)
YakovL
ok, desculpe, var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");não funciona, o segundo faz
YakovL
Parece que esta versão não suporta a remoção de um parâmetro de string de consulta, omitindo o valor. Estou certo?
Jkupczak
12

Sei que essa pergunta é antiga e foi respondida até a morte, mas aqui está minha facada. Estou tentando reinventar a roda aqui porque estava usando a resposta atualmente aceita e o manuseio incorreto dos fragmentos de URL recentemente me mordeu em um projeto.

A função está abaixo. É bastante longo, mas foi feito para ser o mais resiliente possível. Eu adoraria sugestões para encurtá-lo / melhorá-lo. Eu montei uma pequena suíte de testes jsFiddle para ele (ou outras funções semelhantes). Se uma função pode passar em todos os testes lá, eu digo que provavelmente é bom ir.

Atualização: deparei-me com uma função interessante para usar o DOM para analisar URLs , então incorporei essa técnica aqui. Torna a função mais curta e mais confiável. Adereços para o autor dessa função.

/**
 * Add or update a query string parameter. If no URI is given, we use the current
 * window.location.href value for the URI.
 * 
 * Based on the DOM URL parser described here:
 * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/
 *
 * @param   (string)    uri     Optional: The URI to add or update a parameter in
 * @param   (string)    key     The key to add or update
 * @param   (string)    value   The new value to set for key
 *
 * Tested on Chrome 34, Firefox 29, IE 7 and 11
 */
function update_query_string( uri, key, value ) {

    // Use window URL if no query string is provided
    if ( ! uri ) { uri = window.location.href; }

    // Create a dummy element to parse the URI with
    var a = document.createElement( 'a' ), 

        // match the key, optional square brackets, an equals sign or end of string, the optional value
        reg_ex = new RegExp( key + '((?:\\[[^\\]]*\\])?)(=|$)(.*)' ),

        // Setup some additional variables
        qs,
        qs_len,
        key_found = false;

    // Use the JS API to parse the URI 
    a.href = uri;

    // If the URI doesn't have a query string, add it and return
    if ( ! a.search ) {

        a.search = '?' + key + '=' + value;

        return a.href;
    }

    // Split the query string by ampersands
    qs = a.search.replace( /^\?/, '' ).split( /&(?:amp;)?/ );
    qs_len = qs.length; 

    // Loop through each query string part
    while ( qs_len > 0 ) {

        qs_len--;

        // Remove empty elements to prevent double ampersands
        if ( ! qs[qs_len] ) { qs.splice(qs_len, 1); continue; }

        // Check if the current part matches our key
        if ( reg_ex.test( qs[qs_len] ) ) {

            // Replace the current value
            qs[qs_len] = qs[qs_len].replace( reg_ex, key + '$1' ) + '=' + value;

            key_found = true;
        }
    }   

    // If we haven't replaced any occurrences above, add the new parameter and value
    if ( ! key_found ) { qs.push( key + '=' + value ); }

    // Set the new query string
    a.search = '?' + qs.join( '&' );

    return a.href;
}
Dominic P
fonte
2
Isso parece realmente bom, casos de teste sólidos + usando o DOM como analisador de URL. No entanto, encontrei dois casos: example.com/?param=val& => example.com/?param=val&&new=key --double & e example.com/team => example.com/team?new=key esperado: team /? new = key algum redirecionamento / team? new = key para / team / e as consultas são perdidas.
Timar Ivo Batis 28/09
11
Obrigado pelo caso de teste com falha. Eu atualizei o violino. Essa primeira é difícil. Alguma idéia de como consertar a função? O segundo deve ser tratado sem problemas e já está coberto no conjunto de testes. Talvez eu não te entenda. Sinta-se à vontade para mexer no violino de teste para demonstrar o que está vendo.
Dominic P
Adicionei alguns casos de teste que encontrei e soluções alternativas. Tentei usar o DOM o máximo possível. Principalmente eu precisava disso para trabalhar também para links relativos dentro do mesmo domínio. jsfiddle.net/Timar/7sjrhbm3
Timar Ivo Batis 31/10
11
@braed Gosto da abordagem porque deixa o trabalho pesado para o navegador. Como você vê em muitas respostas aqui, esse problema não é tão simples quanto parece. Existem MUITOS casos de canto que uma solução precisa cobrir. A maioria deles é coberta gratuitamente quando você utiliza o DOM.
Dominic P
11
@ Braed com certeza basta dar uma olhada na suíte de testes que eu vinculei na resposta. Muitas soluções aqui que não dependem do DOM falham porque não são responsáveis ​​por todos os casos extremos listados. Quanto à leitura, pode ser instrutivo verificar o módulo de URL para node.js. Não está diretamente relacionado, mas fornece uma idéia da complexidade envolvida nas seqüências de URL.
Dominic P
11

window.location.search é leitura / gravação.

No entanto, modificar a string de consulta redirecionará a página em que você está e causará uma atualização do servidor.

Se o que você está tentando fazer é manter o estado do lado do cliente (e potencialmente torná-lo compatível com favoritos), convém modificar o hash da URL em vez da string de consulta, que mantém você na mesma página (window.location. hash é leitura / gravação). É assim que sites como o twitter.com fazem isso.

Você também deseja que o botão voltar funcione, terá que vincular eventos javascript ao evento de alteração de hash, um bom plugin para isso é http://benalman.com/projects/jquery-hashchange-plugin/

Garota
fonte
4
O Twitter não modifica mais o hash! Hash está morto, bem-vindo à API do histórico !
Alba Mendez
está longe de morrer. Eu acho que você está vivendo em uma terra dos sonhos mágica, onde a compatibilidade do navegador herdado não é motivo de preocupação. esse pode ser o seu caso, mas certamente não é o caso de todos nós (ou de fato a maioria de nós). talvez morrendo é mais apropriado ...
AaronHS
11
Um ano depois, parece que o único navegador semi-recente que não o suporta é o IE 9
Douglas
11

Se não estiver definido ou desejar atualizar com um novo valor, você poderá usar:

window.location.search = 'param=value'; // or param=new_value

A propósito, isso é em Javascript simples.

EDITAR

Você pode tentar usar o plugin jquery query-object

window.location.search = jQuery.query.set ("param", 5);

tradyblix
fonte
11
isso não manterá nenhum outro parâmetro de string de consulta no URL.
Amador #
você está certo, eu peço desculpas .. como uma atualização, eu adicionei uma outra opção para a minha resposta :)
tradyblix
Isso não está funcionando, porque não redefine um valor. "adicionar ou atualizar"
Paolo Falomo 10/10
9

Aqui está minha abordagem: A location.params()função (mostrada abaixo) pode ser usada como getter ou setter. Exemplos:

Dado que o URL é http://example.com/?foo=bar&baz#some-hash,

  1. location.params()irá retornar um objeto com todos os parâmetros de consulta: {foo: 'bar', baz: true}.
  2. location.params('foo') retornará 'bar' .
  3. location.params({foo: undefined, hello: 'world', test: true})alterará o URL para http://example.com/?baz&hello=world&test#some-hash.

Aqui está a params()função, que pode opcionalmente ser atribuída ao window.locationobjeto.

location.params = function(params) {
  var obj = {}, i, parts, len, key, value;

  if (typeof params === 'string') {
    value = location.search.match(new RegExp('[?&]' + params + '=?([^&]*)[&#$]?'));
    return value ? value[1] : undefined;
  }

  var _params = location.search.substr(1).split('&');

  for (i = 0, len = _params.length; i < len; i++) {
    parts = _params[i].split('=');
    if (! parts[0]) {continue;}
    obj[parts[0]] = parts[1] || true;
  }

  if (typeof params !== 'object') {return obj;}

  for (key in params) {
    value = params[key];
    if (typeof value === 'undefined') {
      delete obj[key];
    } else {
      obj[key] = value;
    }
  }

  parts = [];
  for (key in obj) {
    parts.push(key + (obj[key] === true ? '' : '=' + obj[key]));
  }

  location.search = parts.join('&');
};
Jake
fonte
6

Essa é a minha preferência e abrange os casos em que consigo pensar. Alguém pode pensar em uma maneira de reduzi-lo a uma única substituição?

function setParam(uri, key, val) {
    return uri
        .replace(RegExp("([?&]"+key+"(?=[=&#]|$)[^#&]*|(?=#|$))"), "&"+key+"="+encodeURIComponent(val))
        .replace(/^([^?&]+)&/, "$1?");
}
Adam Leggett
fonte
Também não muito poucos casos de teste por Dominic P stackoverflow.com/a/23529943/8385841
Timar Ivo Batis
5

Eu sei que isso é bastante antigo, mas eu quero disparar minha versão de trabalho aqui.

function addOrUpdateUrlParam(uri, paramKey, paramVal) {
  var re = new RegExp("([?&])" + paramKey + "=[^&#]*", "i");
  if (re.test(uri)) {
    uri = uri.replace(re, '$1' + paramKey + "=" + paramVal);
  } else {
    var separator = /\?/.test(uri) ? "&" : "?";
    uri = uri + separator + paramKey + "=" + paramVal;
  }
  return uri;
}

jQuery(document).ready(function($) {
  $('#paramKey,#paramValue').on('change', function() {
    if ($('#paramKey').val() != "" && $('#paramValue').val() != "") {
      $('#uri').val(addOrUpdateUrlParam($('#uri').val(), $('#paramKey').val(), $('#paramValue').val()));
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input style="width:100%" type="text" id="uri" value="http://www.example.com/text.php">
<label style="display:block;">paramKey
  <input type="text" id="paramKey">
</label>
<label style="display:block;">paramValue
  <input type="text" id="paramValue">
</label>

NOTA Esta é uma versão modificada do @elreimundo

Paolo Falomo
fonte
2

Minha opinião a partir daqui (compatível com "use strict"; realmente não usa jQuery):

function decodeURIParams(query) {
  if (query == null)
    query = window.location.search;
  if (query[0] == '?')
    query = query.substring(1);

  var params = query.split('&');
  var result = {};
  for (var i = 0; i < params.length; i++) {
    var param = params[i];
    var pos = param.indexOf('=');
    if (pos >= 0) {
        var key = decodeURIComponent(param.substring(0, pos));
        var val = decodeURIComponent(param.substring(pos + 1));
        result[key] = val;
    } else {
        var key = decodeURIComponent(param);
        result[key] = true;
    }
  }
  return result;
}

function encodeURIParams(params, addQuestionMark) {
  var pairs = [];
  for (var key in params) if (params.hasOwnProperty(key)) {
    var value = params[key];
    if (value != null) /* matches null and undefined */ {
      pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(value))
    }
  }
  if (pairs.length == 0)
    return '';
  return (addQuestionMark ? '?' : '') + pairs.join('&');
}

//// alternative to $.extend if not using jQuery:
// function mergeObjects(destination, source) {
//   for (var key in source) if (source.hasOwnProperty(key)) {
//     destination[key] = source[key];
//   }
//   return destination;
// }

function navigateWithURIParams(newParams) {
  window.location.search = encodeURIParams($.extend(decodeURIParams(), newParams), true);
}

Exemplo de uso:

// add/update parameters
navigateWithURIParams({ foo: 'bar', boz: 42 });

// remove parameter
navigateWithURIParams({ foo: null });

// submit the given form by adding/replacing URI parameters (with jQuery)
$('.filter-form').submit(function(e) {
  e.preventDefault();
  navigateWithURIParams(decodeURIParams($(this).serialize()));
});
Andrey Tarantsov
fonte
2

Com base na resposta que @ellemayo deu, criei a seguinte solução que permite desativar a tag hash, se desejado:

function updateQueryString(key, value, options) {
    if (!options) options = {};

    var url = options.url || location.href;
    var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"), hash;

    hash = url.split('#');
    url = hash[0];
    if (re.test(url)) {
        if (typeof value !== 'undefined' && value !== null) {
            url = url.replace(re, '$1' + key + "=" + value + '$2$3');
        } else {
            url = url.replace(re, '$1$3').replace(/(&|\?)$/, '');
        }
    } else if (typeof value !== 'undefined' && value !== null) {
        var separator = url.indexOf('?') !== -1 ? '&' : '?';
        url = url + separator + key + '=' + value;
    }

    if ((typeof options.hash === 'undefined' || options.hash) &&
        typeof hash[1] !== 'undefined' && hash[1] !== null)
        url += '#' + hash[1];
    return url;
}

Chame assim:

updateQueryString('foo', 'bar', {
    url: 'http://my.example.com#hash',
    hash: false
});

Resulta em:

http://my.example.com?foo=bar
RuubW
fonte
Qualificação estilística: typeof value !== 'undefined' && value !== nullé mais explícita, mas value != nullsignifica a mesma coisa e é mais concisa.
eppsilon
2

Aqui está uma versão mais curta que cuida de

  • consulta com ou sem um determinado parâmetro
  • consulta com vários valores de parâmetro
  • consulta contendo hash

Código:

var setQueryParameter = function(uri, key, value) {
  var re = new RegExp("([?&])("+ key + "=)[^&#]*", "g");
  if (uri.match(re)) 
    return uri.replace(re, '$1$2' + value);

  // need to add parameter to URI
  var paramString = (uri.indexOf('?') < 0 ? "?" : "&") + key + "=" + value;
  var hashIndex = uri.indexOf('#');
  if (hashIndex < 0)
    return uri + paramString;
  else
    return uri.substring(0, hashIndex) + paramString + uri.substring(hashIndex);
}

A descrição do regex pode ser encontrada aqui .

NOTA : Esta solução é baseada na resposta @amateur, mas com muitas melhorias.

MaxZoom
fonte
2

Código que anexa uma lista de parâmetros a um URL existente usando ES6 e jQuery:

class UrlBuilder {
    static appendParametersToUrl(baseUrl, listOfParams) {

        if (jQuery.isEmptyObject(listOfParams)) {
            return baseUrl;
        }

        const newParams = jQuery.param(listOfParams);

        let partsWithHash = baseUrl.split('#');
        let partsWithParams = partsWithHash[0].split('?');

        let previousParams = '?' + ((partsWithParams.length === 2) ? partsWithParams[1] + '&' : '');
        let previousHash = (partsWithHash.length === 2) ? '#' + partsWithHash[1] : '';

        return partsWithParams[0] + previousParams + newParams + previousHash;
    }
}

Onde listOfParams é como

const listOfParams = {
    'name_1': 'value_1',
    'name_2': 'value_2',
    'name_N': 'value_N',
};

Exemplo de uso:

    UrlBuilder.appendParametersToUrl(urlBase, listOfParams);

Testes rápidos:

    url = 'http://hello.world';
    console.log('=> ', UrlParameters.appendParametersToUrl(url, null));
    // Output:  http://hello.world

    url = 'http://hello.world#h1';
    console.log('=> ', UrlParameters.appendParametersToUrl(url, null));
    // Output:  http://hello.world#h1

    url = 'http://hello.world';
    params = {'p1': 'v1', 'p2': 'v2'};
    console.log('=> ', UrlParameters.appendParametersToUrl(url, params));
    // Output: http://hello.world?p1=v1&p2=v2

    url = 'http://hello.world?p0=v0';
    params = {'p1': 'v1', 'p2': 'v2'};
    console.log('=> ', UrlParameters.appendParametersToUrl(url, params));
    // Output: http://hello.world?p0=v0&p1=v1&p2=v2

    url = 'http://hello.world#h1';
    params = {'p1': 'v1', 'p2': 'v2'};
    console.log('=> ', UrlParameters.appendParametersToUrl(url, params));
   // Output: http://hello.world?p1=v1&p2=v2#h1

    url = 'http://hello.world?p0=v0#h1';
    params = {'p1': 'v1', 'p2': 'v2'};
    console.log('=> ', UrlParameters.appendParametersToUrl(url, params));
    // Output: http://hello.world?p0=v0&p1=v1&p2=v2#h1
Samuel Vicent
fonte
1

Uma abordagem diferente sem usar expressões regulares . Suporta âncoras 'hash' no final do URL, bem como vários caracteres de interrogação (?). Deve ser um pouco mais rápido que a abordagem de expressão regular.

function setUrlParameter(url, key, value) {
  var parts = url.split("#", 2), anchor = parts.length > 1 ? "#" + parts[1] : '';
  var query = (url = parts[0]).split("?", 2);
  if (query.length === 1) 
    return url + "?" + key + "=" + value + anchor;

  for (var params = query[query.length - 1].split("&"), i = 0; i < params.length; i++)
    if (params[i].toLowerCase().startsWith(key.toLowerCase() + "="))
      return params[i] = key + "=" + value, query[query.length - 1] = params.join("&"), query.join("?") + anchor;

  return url + "&" + key + "=" + value + anchor
}
cwills
fonte
1

Use esta função para adicionar, remover e modificar parâmetros de string de consulta do URL com base em jquery

/**
@param String url
@param object param {key: value} query parameter
*/
function modifyURLQuery(url, param){
    var value = {};

    var query = String(url).split('?');

    if (query[1]) {
        var part = query[1].split('&');

        for (i = 0; i < part.length; i++) {
            var data = part[i].split('=');

            if (data[0] && data[1]) {
                value[data[0]] = data[1];
            }
        }
    }

    value = $.extend(value, param);

    // Remove empty value
    for (i in value){
        if(!value[i]){
            delete value[i];
        }
    }

    // Return url with modified parameter
    if(value){
        return query[0] + '?' + $.param(value);
    } else {
        return query[0];
    }
}

Adicione novo e modifique o parâmetro existente para o URL

var new_url = modifyURLQuery("http://google.com?foo=34", {foo: 50, bar: 45});
// Result: http://google.com?foo=50&bar=45

Remover existente

var new_url = modifyURLQuery("http://google.com?foo=50&bar=45", {bar: null});
// Result: http://google.com?foo=50
Jay Padaliya
fonte
1

Usando jQuerypodemos fazer como abaixo

var query_object = $.query_string;
query_object["KEY"] = "VALUE";
var new_url = window.location.pathname + '?'+$.param(query_object)

Na variável new_url, teremos novos parâmetros de consulta.

Referência: http://api.jquery.com/jquery.param/

anjaneyulubatta505
fonte
0

Para dar um exemplo de código para modificar, window.location.searchconforme sugerido por Gal e tradyblix:

var qs = window.location.search || "?";
var param = key + "=" + value; // remember to URI encode your parameters
if (qs.length > 1) {
    // more than just the question mark, so append with ampersand
    qs = qs + "&";
}
qs = qs + param;
window.location.search = qs;
Risadinha
fonte
0

Código de script Java para localizar uma sequência de consulta específica e substituir seu valor *

('input.letter').click(function () {
                //0- prepare values
                var qsTargeted = 'letter=' + this.value; //"letter=A";
                var windowUrl = '';
                var qskey = qsTargeted.split('=')[0];
                var qsvalue = qsTargeted.split('=')[1];
                //1- get row url
                var originalURL = window.location.href;
                //2- get query string part, and url
                if (originalURL.split('?').length > 1) //qs is exists
                {
                    windowUrl = originalURL.split('?')[0];
                    var qs = originalURL.split('?')[1];
                    //3- get list of query strings
                    var qsArray = qs.split('&');
                    var flag = false;
                    //4- try to find query string key
                    for (var i = 0; i < qsArray.length; i++) {
                        if (qsArray[i].split('=').length > 0) {
                            if (qskey == qsArray[i].split('=')[0]) {
                                //exists key
                                qsArray[i] = qskey + '=' + qsvalue;
                                flag = true;
                                break;
                            }
                        }
                    }
                    if (!flag)//   //5- if exists modify,else add
                    {
                        qsArray.push(qsTargeted);
                    }
                    var finalQs = qsArray.join('&');
                    //6- prepare final url
                    window.location = windowUrl + '?' + finalQs;
                }
                else {
                    //6- prepare final url
                    //add query string
                    window.location = originalURL + '?' + qsTargeted;
                }
            })
        });
Mohamed.Abdo
fonte
0

Sim, eu tive um problema em que minha string de consulta iria estourar e duplicar, mas isso ocorreu devido à minha própria lentidão. então eu toquei um pouco e trabalhei com js jquery (realmente chiar) e C # magick.

Então, acabei de perceber que, após o servidor concluir os valores passados, os valores não importam mais, não há reutilização; se o cliente quisesse fazer a mesma coisa, evidentemente, sempre haverá uma nova solicitação, mesmo que seja a mesmos parâmetros sendo passados. E isso é tudo do lado do cliente, portanto, alguns cache / cookies etc. podem ser legais nesse sentido.

JS:

$(document).ready(function () {
            $('#ser').click(function () {
                SerializeIT();
            });
            function SerializeIT() {
                var baseUrl = "";
                baseUrl = getBaseUrlFromBrowserUrl(window.location.toString());
                var myQueryString = "";
                funkyMethodChangingStuff(); //whatever else before serializing and creating the querystring
                myQueryString = $('#fr2').serialize();
                window.location.replace(baseUrl + "?" + myQueryString);
            }
            function getBaseUrlFromBrowserUrl(szurl) {
                return szurl.split("?")[0];
            } 
            function funkyMethodChangingStuff(){
               //do stuff to whatever is in fr2
            }
        });

HTML:

<div id="fr2">
   <input type="text" name="qURL" value="http://somewhere.com" />
   <input type="text" name="qSPart" value="someSearchPattern" />
</div>
<button id="ser">Serialize! and go play with the server.</button>

C #:

    using System.Web;
    using System.Text;
    using System.Collections.Specialized;

    public partial class SomeCoolWebApp : System.Web.UI.Page
    {
        string weburl = string.Empty;
        string partName = string.Empty;

        protected void Page_Load(object sender, EventArgs e)
        {
            string loadurl = HttpContext.Current.Request.RawUrl;
            string querySZ = null;
            int isQuery = loadurl.IndexOf('?');
            if (isQuery == -1) { 
                //If There Was no Query
            }
            else if (isQuery >= 1) {
                querySZ = (isQuery < loadurl.Length - 1) ? loadurl.Substring(isQuery + 1) : string.Empty;
                string[] getSingleQuery = querySZ.Split('?');
                querySZ = getSingleQuery[0];

                NameValueCollection qs = null;
                qs = HttpUtility.ParseQueryString(querySZ);

                weburl = qs["qURL"];
                partName = qs["qSPart"];
                //call some great method thisPageRocks(weburl,partName); or whatever.
          }
      }
  }

A crítica é bem-vinda (essa foi uma mistura noturna, fique à vontade para observar os ajustes). Se isso ajudou em tudo, dê um like, Happy Coding.

Sem duplicatas, cada solicitação é única como você a modificou e, devido à forma como isso é estruturado, é fácil adicionar mais consultas dinamicamente dentro do domínio.

LokizFenrir
fonte
0

Aqui está um método alternativo usando as propriedades embutidas do elemento HTML âncora:

  • Lida com parâmetros com vários valores.
  • Não há risco de modificar o fragmento # ou qualquer outra coisa que não seja a própria string de consulta.
  • Pode ser um pouco mais fácil de ler? Mas é mais longo.

    var a = document.createElement('a'),

	getHrefWithUpdatedQueryString = function(param, value) {
	    return updatedQueryString(window.location.href, param, value);
	},

	updatedQueryString = function(url, param, value) {
	    /*
	     A function which modifies the query string 
             by setting one parameter to a single value.

	     Any other instances of parameter will be removed/replaced.
	     */
	    var fragment = encodeURIComponent(param) + 
                           '=' + encodeURIComponent(value);

	    a.href = url;

	    if (a.search.length === 0) {
		a.search = '?' + fragment;
	    } else {
		var didReplace = false,
		    // Remove leading '?'
		    parts = a.search.substring(1)
		// Break into pieces
			.split('&'),

		    reassemble = [],
		    len = parts.length;

		for (var i = 0; i < len; i++) {
		    
		    var pieces = parts[i].split('=');
		    if (pieces[0] === param) {
			if (!didReplace) {
			    reassemble.push('&' + fragment);
			    didReplace = true;
			}
		    } else {
			reassemble.push(parts[i]);
		    }
		}

		if (!didReplace) {
		    reassemble.push('&' + fragment);
		}

		a.search = reassemble.join('&');
	    }

	    return a.href;
	};

GlennS
fonte
0

se você deseja definir vários parâmetros de uma vez:

function updateQueryStringParameters(uri, params) {
    for(key in params){
      var value = params[key],
          re = new RegExp("([?&])" + key + "=.*?(&|$)", "i"),
          separator = uri.indexOf('?') !== -1 ? "&" : "?";
      if (uri.match(re)) {
        uri = uri.replace(re, '$1' + key + "=" + value + '$2');
      }
      else {
        uri = uri + separator + key + "=" + value;
      }
    }
    return uri;
}

mesma função que @ amateur

Se o jslint fornecer um erro, adicione isso após o loop for

if(params.hasOwnProperty(key))
Rachid O
fonte
Não manipula hashes ou parâmetros não atribuídos a um valor ( http://abc.def/?a&b&c).
precisa
0

Há muitas respostas estranhas e desnecessariamente complicadas nesta página. O mais bem classificado, @ amador, é muito bom, embora tenha um pouco de cotão desnecessário no RegExp. Aqui está uma solução um pouco mais ideal com o RegExp mais limpo e uma replacechamada mais limpa :

function updateQueryStringParamsNoHash(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=[^&]*", "i");
  return re.test(uri)
       ? uri.replace(re, '$1' + key + "=" + value)
       : uri + separator + key + "=" + value
  ;
}

Como um bônus adicional, se urinão for uma string, você não receberá erros por tentar chamar matchou replacealgo que pode não implementar esses métodos.

E se você quiser lidar com o caso de um hash (e você já fez uma verificação de HTML formatado corretamente), poderá aproveitar a função existente em vez de escrever uma nova função contendo a mesma lógica:

function updateQueryStringParams(url, key, value) {
    var splitURL = url.split('#');
    var hash = splitURL[1];
    var uri = updateQueryStringParamsNoHash(splitURL[0]);
    return hash == null ? uri : uri + '#' + hash;
}

Ou você pode fazer algumas pequenas alterações na excelente resposta de @ Adam:

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=[^&#]*", "i");
  if (re.test(uri)) {
    return uri.replace(re, '$1' + key + "=" + value);
  } else {
    var matchData = uri.match(/^([^#]*)(#.*)?$/);
    var separator = /\?/.test(uri) ? "&" : "?";    
    return matchData[0] + separator + key + "=" + value + (matchData[1] || '');
  }
}
elreimundo
fonte
2
Este é um colchete ausente na última função: var matchData = uri.match (/^([^#,95*)(#.*)?$/
Jammer
separatornão está definido em updateQueryStringParamsNoHash. Em updateQueryStringParameter, tudo quebra se o parâmetro que você está substituindo não recebe um valor (por exemplo http://abc.def/?a&b&c).
Adam Leggett
0

Isso deve servir ao propósito:

function updateQueryString(url, key, value) {
    var arr =  url.split("#");
    var url = arr[0];
    var fragmentId = arr[1];
    var updatedQS = "";
    if (url.indexOf("?") == -1) {
        updatedQS = encodeURIComponent(key) + "=" + encodeURIComponent(value);
    }
    else {
        updatedQS = addOrModifyQS(url.substring(url.indexOf("?") + 1), key, value); 
    }
    url = url.substring(0, url.indexOf("?")) + "?" + updatedQS;
    if (typeof fragmentId !== 'undefined') {
        url = url + "#" + fragmentId;
    }
    return url;
}

function addOrModifyQS(queryStrings, key, value) {
    var oldQueryStrings = queryStrings.split("&");
    var newQueryStrings = new Array();
    var isNewKey = true;
    for (var i in oldQueryStrings) {
        var currItem = oldQueryStrings[i];
        var searchKey = key + "=";
        if (currItem.indexOf(searchKey) != -1) {
            currItem = encodeURIComponent(key) + "=" + encodeURIComponent(value);
            isNewKey = false;
        }
        newQueryStrings.push(currItem);
    }
    if (isNewKey) {
        newQueryStrings.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
    }
    return newQueryStrings.join("&");
}   
mmuzahid
fonte