Stringa di query JavaScript [chiusa]


106

Esiste una libreria JavaScript che crea un dizionario dalla stringa di query, ASP.NETdallo stile?

Qualcosa che può essere usato come:

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

La "stringa di query" è chiamata qualcos'altro al di fuori del .NETregno? Perché non viene location.searchsuddiviso in una raccolta chiave / valore ?

EDIT : ho scritto la mia funzione, ma una delle principali librerie JavaScript lo fa?





1
@davidtaubmann quello è più vecchio, sarebbe inverso. È buffo che essenzialmente chiedano la stessa cosa, ma a causa del formato della domanda uno ha trasformato la gloria in quello della comunità e l'altro è stato chiuso come fuori tema.
Andre Figueiredo

Risposte:


11

37
Dovrebbe essere nativo di jquery
gcb

@EvanMulawski Thanks. Il plug-in è appena scomparso a quanto pare. Ho aggiunto un collegamento diverso, che potrebbe aiutare.
Shadow2531

Il metodo fornito da CMS è più semplice e pulito. Esp. se non stai già usando jquery.
jcoffland

1
Puoi fare riferimento a questa libreria per farlo - github.com/Mikhus/jsurl
Mikhus

1
Ecco il link corretto: plugins.jquery.com/query-object
thexfactor

230

È possibile estrarre le coppie chiave / valore dalla proprietà location.search , questa proprietà ha la parte dell'URL che segue il? simbolo, compreso il? simbolo.

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
Questa non è una vittoria. Cosa succede se il valore di una chiave contiene il carattere "="? Ad esempio dork.com/?equation=10=2. Si potrebbe sostenere che DOVREBBE essere codificato in URL, ma sicuramente non deve esserlo. Una volta ho commesso l'errore di scrivere una funzione ingenua come questa. Esistono più casi limite di cui questa funzione tiene conto.
JamesBrownIsDead

6
@ James, ho dimenticato di dire che un paio di mesi fa ho modificato la funzione, ora può gestire correttamente il tuo esempio dork.com/?equation=10=2...
CMS

2
@CMS questo non gestisce la possibilità di un array in una stringa di query che è rappresentata come tale, ?val=foo&val=bar&val=baz come lo accoglieresti?
Russ Bradberry

2
@RussBradberry Non puoi davvero avere val=foo&val=bar&val=baz; dovrebbe essereval[]=foo&val[]=bar&val[]=baz
Brian Driscoll

1
Mi sembrava incompleto quando i miei valori avevano spazi e le mie variabili finivano con %20la s, quindi ho sostituito result[keyValuePair[0]] = keyValuePair[1] || '';conresult[keyValuePair[0]] = decodeURIComponent((keyValuePair[1]+'').replace(/\+/g, '%20')) || '';
user24601

22

tl; dr soluzione su una singola riga di codice (ish) utilizzando javascript vanilla

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

Per querystring ?a=1&b=2&c=3&d&erestituisce:

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

chiavi multivalore e caratteri codificati ?

Vedi la risposta originale su Come posso ottenere i valori delle stringhe di query in 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
non è una singola riga - sono diverse righe formattate male!
JonnyRaa

1
Dannazione, non so cosa dire ... Mi hai preso. Ecco una soluzione multilinea: `var queryDict = {}; location.search.substr (1) .split ("&"). forEach (function (item) {queryDict [item.split ("=") [0]] = item.split ("=") [1]; }); `
Qwerty

2
haha mi piace tantissimo! Scusa, lavoravo con qualcuno che diceva "Ho trovato una riga che fa x" e poi ti mostra solo 3 righe con le interruzioni di riga eliminate!
JonnyRaa

@ JonnyLeeds Nessun problema, so esattamente cosa intendi, ma allora, perché scrivere ciascuno dei comandi concatenati su una nuova riga? Poi c'è una funzione data come parametro (i parametri sono solitamente inline) che ha solo una singola assegnazione. Urla di essere inline! : D
Qwerty

1
@ Qwerty, probabilmente è perché il tuo "one-liner" dovrebbe essere riformattato in modo che la lettura non richieda lo scorrimento orizzontale. L'ho aggiustato.
P i

8

Dopo aver trovato questo post, guardandomi ho pensato di dover aggiungere che non credo che la soluzione più votata sia la migliore. Non gestisce i valori degli array (come? A = foo & a = bar - in questo caso mi aspetterei che a restituisca ['foo', 'bar']). Inoltre, per quanto ne so, non tiene conto dei valori codificati, come la codifica dei caratteri esadecimali in cui% 20 rappresenta uno spazio (esempio:? A = Hello% 20World) o il simbolo più utilizzato per rappresentare uno spazio (esempio :? a = Hello + World).

Node.js offre soluzioni che sembrano molto complete per l'analisi delle stringhe di query. Sarebbe facile da estrarre e utilizzare nel tuo progetto poiché è abbastanza ben isolato e con una licenza permissiva.

Il codice può essere visualizzato qui: https://github.com/joyent/node/blob/master/lib/querystring.js

I test di Node possono essere visti qui: https://github.com/joyent/node/blob/master/test/simple/test-querystring.js Suggerirei di provare alcuni di questi con la risposta popolare per vedere come li gestisce.

C'è anche un progetto in cui sono stato coinvolto per aggiungere specificamente questa funzionalità. È un port del modulo di analisi delle stringhe di query lib standard di Python. Il mio fork può essere trovato qui: https://github.com/d0ugal/jquery.qeeree


Non c'è solo il prestito del codice da Node, js, è altamente intrecciato.
alfwatt

5

Oppure puoi usare la libreria sugar.js .

Da sugarjs.com:

Object.fromQueryString (str , deep = true )

Converte la stringa di query di un URL in un oggetto. Se deep è falso, la conversione accetterà solo parametri superficiali (cioè nessun oggetto o array con sintassi []) poiché questi non sono universalmente supportati.

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

Esempio:

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

3

Se hai la stringa di query a portata di mano, usa questo:

 /**
 * @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);

È più o meno lo stesso del codice "Aggiornamento: non è necessario utilizzare regex" nella risposta con il voto più alto sopra. C'è anche un sacco di codice simile in questa domanda ). Ti mancano decodeURIComponentalmeno le stringhe estratte.
Rup

@Rup, l'aggiornamento è stato effettuato dopo questa risposta.
Qwerty

@Qwerty No, non lo era: l'aggiornamento era febbraio 2013, mentre questa risposta è stata quasi un anno dopo, nel febbraio 2014. Ma chi se ne frega, c'è un sacco di codice simile che vola in giro. I miei commenti sullo decodeURIComponentstand, però.
Rup

@ Rup Yup, scusa. E sì.
Qwerty

2

Vale la pena notare che la libreria menzionata da John Slegers ha una dipendenza jQuery, tuttavia ecco una versione che è Javascript vanilla.

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

Avrei semplicemente commentato il suo post, ma mi manca la reputazione per farlo. : /

Esempio:

L'esempio seguente elabora la seguente stringa di query, sebbene irregolare:

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


In realtà, ho rimosso la dipendenza jQuery nel codice che ho fornito nella mia risposta ;-)
John Slegers

2

Il codice

Questo Gist di Eldon McGuinness è di gran lunga l'implementazione più completa di un parser di stringhe di query JavaScript che ho visto finora.

Sfortunatamente, è scritto come plugin jQuery.

L'ho riscritto in vanilla JS e ho apportato alcuni miglioramenti:

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

Come usarlo

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

Produzione

{
  "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"
  ]
}

Vedi anche questo 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]);
        }
    }
}

Puoi anche .toLowerCase () il nome se vuoi che la corrispondenza hfname non faccia distinzione tra maiuscole e minuscole.
Shadow2531

Puoi anche verificare se il valore è vuoto o meno. In tal caso, puoi saltare l'aggiunta della voce in modo che l'array contenga solo valori non vuoti.
Shadow2531

1
unescape () non gestisce le sequenze UTF-8, quindi potresti voler usare decodeURIComponent (). Tuttavia, se vuoi che i + chars vengano decodificati in spazi, esegui .replace (/ \ + / g, "") sulla stringa prima della decodifica.
Shadow2531

1

Mi piace mantenerlo semplice, leggibile e piccolo.

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

Esempio:

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

1

Funzione che ho scritto per un requisito simile a questo con pura manipolazione di stringhe javascript

"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

Pulito, ma a parte il modo in cui rimuovi la parte iniziale ?che è fondamentalmente uguale alle due risposte sopra di te?
Rup

Solo un piccolo miglioramento. Il modo in cui viene utilizzato il metodo lo rende facile per l'utente. L'utente deve solo sapere quale valore della stringa di query ha bisogno.
Pranavan Maru

1

Se stai usando lodash + ES6, ecco una soluzione di una riga: _.object(window.location.search.replace(/(^\?)/, '').split('&').map(keyVal => keyVal.split('=')));


0

Ok, visto che tutti stanno ignorando la mia vera domanda, eh, posterò anche la mia! Ecco cosa ho:

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 i test:

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

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

Intendiamoci, JavaScript non è la mia lingua madre.

Comunque, sto cercando una libreria JavaScript (es. JQuery, Prototype) che ne abbia già una scritta. :)


1
Non sono convinto che tu abbia davvero bisogno di una libreria per fare ciò che equivale a tre righe di codice sopra! Tuttavia, almeno speri che una libreria ricordi decodeURIComponent () sia la chiave che il valore, qualcosa che ogni frammento di codice pubblicato finora non è riuscito a fare.
bobince

Non hai bisogno di una libreria. Volevo confrontare la mia implementazione con una in una libreria in modo da poter vedere se mi mancavano casi limite. :)
core

javascript non è la tua lingua madre cosa significa, dovresti impararlo anche se hai bisogno di una libreria da usare
Marwan

0

Basandosi sulla risposta di @CMS ho quanto segue (in CoffeeScript che può essere facilmente convertito in 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

Puoi facilmente afferrare ciò di cui hai bisogno con:

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

La vittoria qui è un'interfaccia orientata agli oggetti (invece che funzionale) e può essere eseguita su qualsiasi stringa (non solo location.search).

Se stai già utilizzando una libreria JavaScript questa funzione fa già esistere. Ad esempio, ecco la versione di Prototype

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.