String de consulta JavaScript [fechada]


106

Existe alguma biblioteca JavaScript que faz um dicionário da string de consulta, ASP.NETestilo?

Algo que pode ser usado como:

var query = window.location.querystring["query"]?

A "string de consulta" é chamada de outra coisa fora do .NETreino? Por que não é location.searchdividido em uma coleção de chave / valor ?

EDIT : Eu escrevi minha própria função, mas alguma biblioteca JavaScript importante faz isso?





1
@davidtaubmann se for mais velho, seria o inverso. Engraçado que eles essencialmente perguntam o mesmo, mas devido ao formato da pergunta, um deles ganhou a glória transformada em comunidade e outro foi encerrado como fora do tópico.
Andre Figueiredo

Respostas:


11

37
Deve ser nativo de jquery
gcb

@EvanMulawski Obrigado. Parece que o plug-in simplesmente desapareceu. Eu adicionei um link diferente, o que pode ajudar.
Shadow2531

O método fornecido pelo CMS é mais fácil e limpo. Esp. se você ainda não estiver usando jquery.
jcoffland

1
Você pode consultar esta biblioteca para fazer isso - github.com/Mikhus/jsurl
Mikhus

1
Aqui está o link adequado: plugins.jquery.com/query-object
thexfactor

230

Você pode extrair os pares de chave / valor da propriedade location.search , esta propriedade tem a parte do URL que segue o? símbolo, incluindo o? símbolo.

function getQueryString() {
  var result = {}, queryString = location.search.slice(1),
      re = /([^&=]+)=([^&]*)/g, m;

  while (m = re.exec(queryString)) {
    result[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }

  return result;
}

// ...
var myParam = getQueryString()["myParam"];

11
Isso não é uma vitória. E se o valor de uma chave contiver o caractere '='? Por exemplo, dork.com/?equation=10=2. Você pode argumentar que DEVE ser codificado por URL, mas com certeza não precisa ser. Eu cometi o erro de escrever uma função ingênua como esta uma vez. Há mais de um caso extremo para o qual essa função é considerada.
JamesBrownIsDead

6
@James, esqueci de mencionar que alguns meses atrás eu modifiquei a função, agora ela pode lidar corretamente com seu exemplo dork.com/?equation=10=2...
CMS

2
@CMS isso não lida com a possibilidade de uma matriz em uma string de consulta que é representada como tal, ?val=foo&val=bar&val=baz como você acomodaria isso?
Russ Bradberry

2
@RussBradberry Você realmente não pode ter val=foo&val=bar&val=baz; teria que serval[]=foo&val[]=bar&val[]=baz
Brian Driscoll

1
Pareceu-me incompleto quando meus valores tinham espaços e meus vars terminaram com %20's, então substituí result[keyValuePair[0]] = keyValuePair[1] || '';porresult[keyValuePair[0]] = decodeURIComponent((keyValuePair[1]+'').replace(/\+/g, '%20')) || '';
user24601

22

solução tl; dr em uma única linha (ish) de código usando vanilla javascript

var queryDict = {}
location.search.substr(1).split("&").forEach(function(item) {
    queryDict[item.split("=")[0]] = item.split("=")[1]
})

Para querystring, ?a=1&b=2&c=3&d&eele retorna:

> queryDict
a: "1"
b: "2"
c: "3"
d: undefined
e: undefined

chaves com vários valores e caracteres codificados ?

Veja a resposta original em Como posso obter valores de string de consulta em JavaScript?

"?a=1&b=2&c=3&d&e&a=5&a=t%20e%20x%20t&e=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dståle%26car%3Dsaab"
> queryDict
a: ["1", "5", "t e x t"]
b: ["2"]
c: ["3"]
d: [undefined]
e: [undefined, "http://w3schools.com/my test.asp?name=ståle&car=saab"]

8
isso não é uma única linha - são várias linhas formatadas incorretamente!
JonnyRaa de

1
Droga, não sei o que dizer ... Você me pegou. Aqui, tem uma solução multilinha: `var queryDict = {}; location.search.substr (1) .split ("&"). forEach (function (item) {queryDict [item.split ("=") [0]] = item.split ("=") [1]; }); `
Qwerty

2
haha eu amo isso! Desculpe, eu costumava trabalhar com alguém que costumava dizer 'Encontrei um liner que faz x' e depois mostrava apenas 3 linhas sem as quebras de linha!
JonnyRaa de

@JonnyLeeds Não tem problema, eu sei exatamente o que você quer dizer, mas então, por que alguém escreveria cada um dos comandos encadeados em uma nova linha? Depois, há uma função fornecida como parâmetro (os parâmetros são geralmente embutidos) que tem apenas uma única atribuição. Grita para ser embutido! : D
Qwerty

1
@Qwerty, provavelmente é porque seu "one-liner" deve ser reformatado para que sua leitura não exija rolagem horizontal. Eu ajustei isso.
P i

8

Depois de encontrar esta postagem, ao olhar para mim mesmo, pensei que deveria acrescentar que não acho a solução mais votada a melhor. Ele não lida com valores de array (como? A = foo & a = bar - neste caso, eu esperaria obter a para retornar ['foo', 'bar']). Tanto quanto posso dizer, não leva em consideração os valores codificados - como a codificação de caracteres hexadecimais em que% 20 representa um espaço (exemplo:? A = Hello% 20World) ou o símbolo de adição a ser usado para representar um espaço (exemplo :? a = Olá + Mundo).

Node.js oferece o que parece ser uma solução muito completa para análise de string de consulta. Seria fácil retirá-lo e usá-lo em seu próprio projeto, já que está bastante isolado e sob uma licença permissiva.

O código pode ser visto aqui: https://github.com/joyent/node/blob/master/lib/querystring.js

Os testes que o Node possui podem ser vistos aqui: https://github.com/joyent/node/blob/master/test/simple/test-querystring.js Eu sugeriria tentar alguns deles com a resposta popular para ver como isso lida com eles.

Há também um projeto no qual estive envolvido para adicionar especificamente essa funcionalidade. É uma porta do módulo de análise de string de consulta lib padrão do Python. Meu garfo pode ser encontrado aqui: https://github.com/d0ugal/jquery.qeeree


Não há como pegar emprestado o código do Node, js, ele é altamente entrelaçado.
alfwatt

5

Ou você pode usar a biblioteca sugar.js .

De sugarjs.com:

Object.fromQueryString (str , deep = true )

Converte a string de consulta de um URL em um objeto. Se deep for false, a conversão só aceitará parâmetros superficiais (ou seja, nenhum objeto ou matrizes com sintaxe []), pois eles não são universalmente suportados.

Object.fromQueryString('foo=bar&broken=wear') >{"foo":"bar","broken":"wear"}
Object.fromQueryString('foo[]=1&foo[]=2') >{"foo":[1,2]}

Exemplo:

var queryString = Object.fromQueryString(location.search);
var foo = queryString.foo;

3

Se você tiver a querystring em mãos, use isto:

 /**
 * @param qry the querystring
 * @param name name of parameter
 * @returns the parameter specified by name
 * @author eduardo.medeirospereira@gmail.com
 */

function getQueryStringParameter(qry,name){
    if(typeof qry !== undefined && qry !== ""){
        var keyValueArray = qry.split("&");
        for ( var i = 0; i < keyValueArray.length; i++) {
            if(keyValueArray[i].indexOf(name)>-1){
                return keyValueArray[i].split("=")[1];
            }
        }
    }
    return "";
}

2
// How about this
function queryString(qs) {
    var queryStr = qs.substr(1).split("&"),obj={};
    for(var i=0; i < queryStr.length;i++)
        obj[queryStr[i].split("=")[0]] = queryStr[i].split("=")[1];
    return obj;
}

// Usage:
var result = queryString(location.search);

Isso é mais ou menos o mesmo que o código "Atualizar: não há necessidade de usar regex" na resposta com maior votação acima. Também há muitos códigos semelhantes nesta questão ). Você está faltando decodeURIComponentnas strings extraídas, pelo menos.
Rup

@Rup, a atualização foi feita após esta resposta.
Qwerty de

@Qwerty Não, não foi: a atualização foi em fevereiro de 2013, enquanto esta resposta foi quase um ano depois, em fevereiro de 2014. Mas quem se importa, há muitos códigos semelhantes circulando por aí. Meus comentários sobre o decodeURIComponentestande, no entanto.
Rup

@Rup Sim, desculpe. E sim.
Qwerty

2

É importante notar que a biblioteca que John Slegers mencionou tem uma dependência jQuery, porém aqui está uma versão que é Javascript simples.

https://github.com/EldonMcGuinness/querystring.js

Eu teria simplesmente comentado sobre sua postagem, mas não tenho reputação para fazê-lo. : /

Exemplo:

O exemplo abaixo processa a seguinte string de consulta, embora irregular:

?foo=bar&foo=boo&roo=bar;bee=bop;=ghost;=ghost2;&;checkbox%5B%5D=b1;checkbox%5B%5D=b2;dd=;http=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab&http=http%3A%2F%2Fw3schools2.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab 

var qs = "?foo=bar&foo=boo&roo=bar;bee=bop;=ghost;=ghost2;&;checkbox%5B%5D=b1;checkbox%5B%5D=b2;dd=;http=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab&http=http%3A%2F%2Fw3schools2.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab";
//var qs = "?=&=";
//var qs = ""

var results = querystring(qs);

(document.getElementById("results")).innerHTML =JSON.stringify(results, null, 2);
<script 
src="https://rawgit.com/EldonMcGuinness/querystring.js/master/dist/querystring.min.js"></script>
<pre id="results">RESULTS: Waiting...</pre>


Na verdade, eu
removi

2

O código

Este Gist de Eldon McGuinness é de longe a implementação mais completa de um analisador de string de consulta JavaScript que vi até agora.

Infelizmente, ele foi escrito como um plugin jQuery.

Reescrevi como vanilla JS e fiz algumas melhorias:

function parseQuery(str) {
  var qso = {};
  var qs = (str || document.location.search);
  // Check for an empty querystring
  if (qs == "") {
    return qso;
  }
  // Normalize the querystring
  qs = qs.replace(/(^\?)/, '').replace(/;/g, '&');
  while (qs.indexOf("&&") != -1) {
    qs = qs.replace(/&&/g, '&');
  }
  qs = qs.replace(/([\&]+$)/, '');
  // Break the querystring into parts
  qs = qs.split("&");
  // Build the querystring object
  for (var i = 0; i < qs.length; i++) {
    var qi = qs[i].split("=");
    qi = qi.map(function(n) {
      return decodeURIComponent(n)
    });
    if (typeof qi[1] === "undefined") {
      qi[1] = null;
    }
    if (typeof qso[qi[0]] !== "undefined") {

      // If a key already exists then make this an object
      if (typeof (qso[qi[0]]) == "string") {
        var temp = qso[qi[0]];
        if (qi[1] == "") {
          qi[1] = null;
        }
        qso[qi[0]] = [];
        qso[qi[0]].push(temp);
        qso[qi[0]].push(qi[1]);

      } else if (typeof (qso[qi[0]]) == "object") {
        if (qi[1] == "") {
          qi[1] = null;
        }
        qso[qi[0]].push(qi[1]);
      }
    } else {
      // If no key exists just set it as a string
      if (qi[1] == "") {
        qi[1] = null;
      }
      qso[qi[0]] = qi[1];
    }
  }
  return qso;
}

Como usá-lo

var results = parseQuery("?foo=bar&foo=boo&roo=bar;bee=bop;=ghost;=ghost2;&;checkbox%5B%5D=b1;checkbox%5B%5D=b2;dd=;http=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab&http=http%3A%2F%2Fw3schools2.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab");

Resultado

{
  "foo": ["bar", "boo" ],
  "roo": "bar",
  "bee": "bop",
  "": ["ghost", "ghost2"],
  "checkbox[]": ["b1", "b2"],
  "dd": null,
  "http": [
    "http://w3schools.com/my test.asp?name=ståle&car=saab",
    "http://w3schools2.com/my test.asp?name=ståle&car=saab"
  ]
}

Veja também este Fiddle .


1

function decode(s) {
    try {
        return decodeURIComponent(s).replace(/\r\n|\r|\n/g, "\r\n");
    } catch (e) {
        return "";
    }
}
function getQueryString(win) {
    var qs = win.location.search;
    var multimap = {};
    if (qs.length > 1) {
        qs = qs.substr(1);
        qs.replace(/([^=&]+)=([^&]*)/g, function(match, hfname, hfvalue) {
            var name = decode(hfname);
            var value = decode(hfvalue);
            if (name.length > 0) {
                if (!multimap.hasOwnProperty(name)) {
                    multimap[name] = [];
                }
                multimap[name].push(value);
            }
        });
    }
    return multimap;
}
var keys = getQueryString(window);
for (var i in keys) {
    if (keys.hasOwnProperty(i)) {
        for (var z = 0; z < keys[i].length; ++z) {
            alert(i + ":" + keys[i][z]);
        }
    }
}

Você também pode usar .toLowerCase () o nome se quiser que a correspondência de hfname não faça distinção entre maiúsculas e minúsculas.
Shadow2531

Você também pode verificar se o valor está vazio ou não. Se for, você pode pular a adição da entrada para que a matriz contenha apenas valores não vazios.
Shadow2531

1
unescape () não lida com sequências UTF-8, então você pode querer usar decodeURIComponent (). No entanto, se você quiser que os caracteres + sejam decodificados em espaços, execute .replace (/ \ + / g, "") na string antes da decodificação.
Shadow2531

1

Gosto de mantê-lo simples, legível e pequeno.

function searchToObject(search) {
    var pairs = search.substring(1).split("&"),
        obj = {}, pair;

    for (var i in pairs) {
        if (pairs[i] === "") continue;
        pair = pairs[i].split("=");
        obj[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
    }
    return obj;
}

searchToObject(location.search);

Exemplo:

searchToObject('?query=myvalue')['query']; // spits out: 'myvalue'

1

Função que escrevi para um requisito semelhante a este com manipulação de string javascript puro

"http://www.google.lk/?Name=John&Age=20&Gender=Male"

function queryize(sampleurl){
    var tokens = url.split('?')[1].split('&');
    var result = {};

    for(var i=0; i<tokens.length; i++){
        result[tokens[i].split('=')[0]] = tokens[i].split('=')[1];
    }

    return result;
}

Uso:

queryize(window.location.href)['Name'] //returns John
queryize(window.location.href)['Age'] //returns 20
queryize(window.location.href)['Gender'] //returns Male

Legal, mas além da maneira como você remove a liderança, ?isso é basicamente o mesmo que as duas respostas acima de você?
Rup

Apenas uma pequena melhoria. A maneira como o método é usado torna-o fácil para o usuário. O usuário só precisa saber qual valor de string de consulta ele precisa.
Pranavan Maru

1

Se você estiver usando lodash + ES6, aqui está uma solução de uma linha: _.object(window.location.search.replace(/(^\?)/, '').split('&').map(keyVal => keyVal.split('=')));


0

Ok, já que todos estão ignorando minha pergunta real, heh, vou postar a minha também! Aqui está o que tenho:

location.querystring = (function() {

    // The return is a collection of key/value pairs

    var queryStringDictionary = {};

    // Gets the query string, starts with '?'

    var querystring = unescape(location.search);

    // document.location.search is empty if no query string

    if (!querystring) {
        return {};
    }

    // Remove the '?' via substring(1)

    querystring = querystring.substring(1);

    // '&' seperates key/value pairs

    var pairs = querystring.split("&");

    // Load the key/values of the return collection

    for (var i = 0; i < pairs.length; i++) {
        var keyValuePair = pairs[i].split("=");
        queryStringDictionary[keyValuePair[0]] = keyValuePair[1];
    }

    // Return the key/value pairs concatenated

    queryStringDictionary.toString = function() {

        if (queryStringDictionary.length == 0) {
            return "";
        }

        var toString = "?";

        for (var key in queryStringDictionary) {
            toString += key + "=" + queryStringDictionary[key];
        }

        return toString;
    };

    // Return the key/value dictionary

    return queryStringDictionary;
})();

E os testes:

alert(window.location.querystring.toString());

for (var key in location.querystring) {
    alert(key + "=" + location.querystring[key]);
}

Lembre-se de que você pensou, JavaScript não é minha língua nativa.

De qualquer forma, estou procurando uma biblioteca JavaScript (por exemplo, jQuery, Prototype) que já tem uma escrita. :)


1
Não estou convencido de que você realmente precise de uma biblioteca para fazer o que corresponde às três linhas de código acima! Ainda assim, pelo menos você esperaria que uma biblioteca se lembrasse de decodeURIComponent () tanto da chave quanto do valor, algo que todo trecho de código postado até agora não conseguiu fazer.
bobince

Você não precisa de uma biblioteca. Eu queria comparar minha implementação com uma em uma biblioteca para poder ver se estava faltando algum caso extremo. :)
núcleo de

javascript não é sua língua nativa o que significa, você deve aprendê-lo mesmo se precisar de uma biblioteca para usar
Marwan

0

Com base na resposta de @CMS, tenho o seguinte (em CoffeeScript, que pode ser facilmente convertido para JavaScript):

String::to_query = ->
  [result, re, d] = [{}, /([^&=]+)=([^&]*)/g, decodeURIComponent]
  while match = re.exec(if @.match /^\?/ then @.substring(1) else @)
    result[d(match[1])] = d match[2] 
  result

Você pode facilmente pegar o que precisa com:

location.search.to_query()['my_param']

A vitória aqui é uma interface orientada a objetos (em vez de funcional) e pode ser feita em qualquer string (não apenas location.search).

Se você já está usando uma biblioteca JavaScript, esta função já existe. Por exemplo, aqui está a versão do Prototype

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.