Ottieni i valori dell'URL dei parametri della stringa di query con jQuery / Javascript (querystring)


149

Qualcuno sa di un buon modo per scrivere un'estensione jQuery per gestire i parametri della stringa di query? In pratica voglio estendere la ($)funzione magica jQuery in modo da poter fare qualcosa del genere:

$('?search').val(); 

Il che mi avrebbe dato il "test" valore nel seguente URL: http://www.example.com/index.php?search=test.

Ho visto molte funzioni che possono farlo in jQuery e Javascript, ma in realtà voglio estendere jQuery per funzionare esattamente come mostrato sopra. Non sto cercando un plug-in jQuery, sto cercando un'estensione del metodo jQuery.



1
@NicoWesterdale - Ho seguito quel link, ma non ho visto nessuna risposta che risolva questa particolare domanda. Ha detto che vuole esattamente come sopra.
Mrtsherman,

2
Non credo che tu possa farlo, una stringa passata viene analizzata da Sizzler, quindi risolta in una matrice di oggetti DOM. Puoi estendere il matcher per fornire filtri personalizzati, ma non puoi avere un oggetto jquery basato su una stringa.
Andrew,

6
Non è $abbastanza sovraccarico?
Quentin,

1
@mrtsherman Guarda la funzione getParameterByName () nel link che ho fornito. No, non puoi farlo direttamente da $ prompt, ma non è per questo che i selettori jQuery sono. Sta solo selezionando parte di una stringa URL, non sta provando ad accedere a parte del DOM che è ciò che $ () fa. È una cosa totalmente diversa. Se davvero volessi usare jQuery potresti scrivere un plugin che usasse questa sintassi: $ .getParameterByName (param), c'è un esempio più in basso in quella pagina a cui ho collegato che fa esattamente questo. Un po 'inutile però.
Nico Westerdale,

Risposte:


46

Dopo anni di brutte analisi delle stringhe, c'è un modo migliore: URLSearchParams Diamo un'occhiata a come possiamo usare questa nuova API per ottenere valori dalla posizione!

// Supponendo "? Post = 1234 & action = edit"

var urlParams = new URLSearchParams(window.location.search);
console.log(urlParams.has('post')); // true
console.log(urlParams.get('action')); // "edit"
console.log(urlParams.getAll('action')); // ["edit"]
console.log(urlParams.toString()); // "?post=1234&action=edit"
console.log(urlParams.append('active', '1')); // "?

post=1234&action=edit&active=1"

AGGIORNAMENTO: IE non è supportato

usa questa funzione da una risposta qui sotto invece di URLSearchParams

$.urlParam = function (name) {
    var results = new RegExp('[\?&]' + name + '=([^&#]*)')
                      .exec(window.location.search);

    return (results !== null) ? results[1] || 0 : false;
}

console.log($.urlParam('action')); //edit

1
URLSearchParams è supportato da tutti i browser?
divino l'

Oops! oh amico, IE non è supportato !! Ci ho appena provato. Mentre Chrome, FF, Safari non ha alcun problema.
Saurin,

1
@divine - C'è un polyfill per URLSearchParams qui: github.com/WebReflection/url-search-params
Roberto

Se aggiungi un polyfill per browser non supportati, questa soluzione URLSearchParams funziona bene. github.com/ungap/url-search-params
Louisvdw

104

Perché estendere jQuery? Quale sarebbe il vantaggio di estendere jQuery rispetto al semplice fatto di avere una funzione globale?

function qs(key) {
    key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, "\\$&"); // escape RegEx meta chars
    var match = location.search.match(new RegExp("[?&]"+key+"=([^&]+)(&|$)"));
    return match && decodeURIComponent(match[1].replace(/\+/g, " "));
}

http://jsfiddle.net/gilly3/sgxcL/

Un approccio alternativo sarebbe quello di analizzare l'intera stringa di query e archiviare i valori in un oggetto per un uso successivo. Questo approccio non richiede un'espressione regolare ed estende l' window.locationoggetto (ma potrebbe altrettanto facilmente utilizzare una variabile globale):

location.queryString = {};
location.search.substr(1).split("&").forEach(function (pair) {
    if (pair === "") return;
    var parts = pair.split("=");
    location.queryString[parts[0]] = parts[1] &&
        decodeURIComponent(parts[1].replace(/\+/g, " "));
});

http://jsfiddle.net/gilly3/YnCeu/

Anche questa versione fa uso di Array.forEach(), che non è disponibile in modo nativo in IE7 e IE8. Può essere aggiunto utilizzando l'implementazione in MDN , oppure è possibile utilizzare $.each()invece jQuery .


2
Non è comune ma è valido utilizzare punti e virgola anziché e commerciali nei parametri della query.
Muhd,

@Muhd - È "valido" usare qualsiasi delimitatore che ti piace in una stringa di query purché il tuo codice lo capisca. Ma quando viene inviato un modulo, i campi del modulo vengono inviati come name=valuecoppie, separati da &. Se il tuo codice utilizza un formato di querystring personalizzato, ovviamente, dovrai scrivere un parser di querystring personalizzato ovunque venga consumata la querystring, sia sul server che sul client.
gilly3,

2
@nick - Interessante. Ma il loro suggerimento per i server HTTP di trattare i punti e virgola come e commerciali serve solo a rendere HTML più bello quando si utilizza un collegamento per simulare l'invio di un modulo. È solo un suggerimento ed è non standard. Una GETpresentazione di modulo standard è codificata come application/x-www-form-urlencoded, con valori separati da &. Il mio codice gestisce quello standard. Le strutture di url personalizzate come quella che hai collegato avranno bisogno di un parser personalizzato lato server e lato client. Indipendentemente da ciò, l'aggiunta di tale capacità al mio codice sopra sarebbe banale.
gilly3,

1
@gilly infatti - se vuoi un codice portatile devi supportare entrambi
nick

1
Aggiungi "i" a RegExp () in modo che la chiave non faccia distinzione tra maiuscole e minuscole: new RegExp ("[? &]" + Key + "= ([^ &] +) (& | $)", "i"));
Yovav il

94

Il plug -in JQuery jQuery-URL-Parser fa lo stesso lavoro, ad esempio per recuperare il valore del parametro della stringa della query di ricerca , è possibile utilizzare

$.url().param('search');

Questa libreria non è mantenuta attivamente. Come suggerito dall'autore dello stesso plug-in, è possibile utilizzare URI.js .

Oppure puoi usare js-url invece. È abbastanza simile a quello qui sotto.

Quindi puoi accedere alla query param come $.url('?search')


2
Bello. E il codice è di dominio pubblico, quindi non è nemmeno necessario includere i commenti.
Muhd,

4
Buona soluzione ma non funzionerà se ti capita di provare tramite file: //
kampsj,

1
Che cosa c'entra niente, @kampsj
RameshVel

3
Ciao @kampsj, il test con file://protocollo farà sì che molte più cose non funzionino. Puoi creare un server HTML statico molto semplice e veloce con node.js. stackoverflow.com/questions/16333790/…
Jess,

2
Questo plug-in non è più gestito e l'autore stesso suggerisce di utilizzare altri plug-in.
JanErikGunnar,

77

Ho trovato questo gioiello dai nostri amici su SitePoint. https://www.sitepoint.com/url-parameters-jquery/ .

Usando PURE jQuery. L'ho appena usato e ha funzionato. Modificato un po 'per esempio.

//URL is http://www.example.com/mypage?ref=registration&email=bobo@example.com

$.urlParam = function (name) {
    var results = new RegExp('[\?&]' + name + '=([^&#]*)')
                      .exec(window.location.search);

    return (results !== null) ? results[1] || 0 : false;
}

console.log($.urlParam('ref')); //registration
console.log($.urlParam('email')); //bobo@example.com

Usa come vuoi.


Grande. Grazie! Non penso che tu abbia bisogno dell'ultimo tag di parentesi graffa di chiusura.
bhtabor,

Ah sì, hai ragione. Ha modificato il post. Ciò è stato lasciato da qualche istruzione if nel mio codice. Grazie.
ClosDesign,

1
Dovresti usare window.location.search invece di .href - altrimenti, va bene.
BrainSlugs83,

4
Invece di results[1] || 0, devi fare se (risultati) {return results [1]} return 0; i parametri della query bcoz potrebbero non essere presenti affatto. E la modifica gestirà tutti i casi generici.
myDoggyWritesCode

1
Cosa fai se hai qualcosa del genere https://example.com/?c=Order+ID? Quel segno più rimane ancora su questa funzione.
Volomike

47

Questo non è il mio esempio di codice, ma l'ho usato in passato.

//First Add this to extend jQuery

    $.extend({
      getUrlVars: function(){
        var vars = [], hash;
        var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
        for(var i = 0; i < hashes.length; i++)
        {
          hash = hashes[i].split('=');
          vars.push(hash[0]);
          vars[hash[0]] = hash[1];
        }
        return vars;
      },
      getUrlVar: function(name){
        return $.getUrlVars()[name];
      }
    });

    //Second call with this:
    // Get object of URL parameters
    var allVars = $.getUrlVars();

    // Getting URL var by its name
    var byName = $.getUrlVar('name');

2
Non dovresti dividere su '=', tecnicamente va bene avere un secondo uguale nel valore di qualsiasi coppia chiave / valore. - Solo i primi segni di uguale che incontri (per coppia chiave / valore) devono essere trattati come delimitatori. (Inoltre, il segno di uguale non è strettamente richiesto; è possibile avere una chiave senza valore.)
BrainSlugs83

Soluzione pulita. Ha funzionato perfettamente nel mio caso.
JF Gagnon,

$ .extend ({getUrlVars: function () {var vars = [], hash; var hashes = window.location.href.slice (window.location.href.indexOf ('?') + 1) .split ('& '); for (var i = 0; i <hashes.length; i ++) {hash = hashes [i] .split (' = '); var k = hash.shift (); vars.push (k); vars [k] = hash.join ("");} return vars;}, getUrlVar: function (name) {return $ .getUrlVars () [name];}});
Mupinc,

15

Ho scritto una piccola funzione in cui devi solo analizzare il nome del parametro di query. Quindi se hai:? Project = 12 & Mode = 200 & date = 2013-05-27 e vuoi il parametro 'Mode' devi solo analizzare il nome 'Mode' nella funzione:

function getParameterByName( name ){
    var regexS = "[\\?&]"+name+"=([^&#]*)", 
  regex = new RegExp( regexS ),
  results = regex.exec( window.location.search );
  if( results == null ){
    return "";
  } else{
    return decodeURIComponent(results[1].replace(/\+/g, " "));
  }
}

// example caller:
var result =  getParameterByName('Mode');

Se il tuo nome non ha spazzatura, puoi eliminare la prima regex e ha più senso iniziare da location.search
mplungjan

7

Sulla base della risposta di @Rob Neild sopra, ecco un puro adattamento JS che restituisce un semplice oggetto di parametri di stringa di query decodificati (no% 20, ecc.).

function parseQueryString () {
  var parsedParameters = {},
    uriParameters = location.search.substr(1).split('&');

  for (var i = 0; i < uriParameters.length; i++) {
    var parameter = uriParameters[i].split('=');
    parsedParameters[parameter[0]] = decodeURIComponent(parameter[1]);
  }

  return parsedParameters;
}

Non ho visto alcun errore utilizzando questo codice. Quale browser utilizzate? L'ho testato su Firefox, Chrome e Safari attuali.

Sì, scusa, l'ho letto male. Pensavo di averlo visto chiamare un metodo su qualcosa che stava tornando indefinito. Quindi è davvero solo una volta in esecuzione quando non è necessario. Quando la ricerca è "". E ottieni {"": "undefined"}
Jerinaw

Si. Questo potrebbe probabilmente usare un po 'di raffinazione.

1

Scritto in Vanilla Javascript

     //Get URL
     var loc = window.location.href;
     console.log(loc);
     var index = loc.indexOf("?");
     console.log(loc.substr(index+1));
     var splitted = loc.substr(index+1).split('&');
     console.log(splitted);
     var paramObj = [];
     for(var i=0;i<splitted.length;i++){
         var params = splitted[i].split('=');
         var key = params[0];
         var value = params[1];
         var obj = {
             [key] : value
         };
         paramObj.push(obj);
         }
    console.log(paramObj);
    //Loop through paramObj to get all the params in query string.

1
function parseQueryString(queryString) {
    if (!queryString) {
        return false;
    }

    let queries = queryString.split("&"), params = {}, temp;

    for (let i = 0, l = queries.length; i < l; i++) {
        temp = queries[i].split('=');
        if (temp[1] !== '') {
            params[temp[0]] = temp[1];
        }
    }
    return params;
}

Io lo uso

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.