Comment puis-je obtenir des valeurs de chaîne de requête en JavaScript?

2697

Existe-t-il un moyen sans plug-in de récupérer les valeurs de chaîne de requête via jQuery (ou sans)?

Si c'est le cas, comment? Sinon, existe-t-il un plugin qui peut le faire?

Ripounet
la source
J'utilise le plugin getUrlParam décrit dans jQuery-Plugin - getUrlParam (version 2) .
coma
69
Une solution javascript simple sans RegEx: css-tricks.com/snippets/javascript/get-url-variables
Lorenzo Polidori
6
Bien que la meilleure solution à la question mérite sa popularité en raison de son excellente observation que jQuery n'est pas nécessaire, sa méthode de création de nouvelles expressions régulières et de nouvelle analyse de la chaîne de requête pour chaque paramètre souhaité est extrêmement inefficace. Des solutions beaucoup plus efficaces (et polyvalentes) existent depuis longtemps, par exemple dans cet article reproduit ici: htmlgoodies.com/beyond/javascript/article.php/11877_3755006_3/…
Joseph Myers
1
doublon possible de la chaîne de requête JavaScript
4
Joseph, "l'excellente observation que jQuery n'est pas nécessaire"? Bien sûr, ce n'est pas nécessaire. Tout ce que jQuery fait, il le fait en utilisant JavaScript. Les gens n'utilisent pas jQuery car il fait des choses que JavaScript ne peut pas faire. Le point de jQuery est la commodité.
Vladimir Kornea

Réponses:

8331

Mise à jour: sept-2018

Vous pouvez utiliser URLSearchParams qui est simple et prend en charge un navigateur décent (mais pas complet) .

const urlParams = new URLSearchParams(window.location.search);
const myParam = urlParams.get('myParam');

Original

Vous n'avez pas besoin de jQuery à cet effet. Vous pouvez utiliser uniquement du JavaScript pur:

function getParameterByName(name, url) {
    if (!url) url = window.location.href;
    name = name.replace(/[\[\]]/g, '\\$&');
    var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, ' '));
}

Usage:

// query string: ?foo=lorem&bar=&baz
var foo = getParameterByName('foo'); // "lorem"
var bar = getParameterByName('bar'); // "" (present with empty value)
var baz = getParameterByName('baz'); // "" (present with no value)
var qux = getParameterByName('qux'); // null (absent)


Remarque: Si un paramètre est présent plusieurs fois ( ?foo=lorem&foo=ipsum), vous obtiendrez la première valeur ( lorem). Il n'y a pas de norme à ce sujet et les utilisations varient, voir par exemple cette question: Position faisant autorité des clés de requête HTTP GET en double .
REMARQUE: la fonction est sensible à la casse. Si vous préférez un nom de paramètre insensible à la casse, ajoutez le modificateur «i» à RegExp


Il s'agit d'une mise à jour basée sur les nouvelles spécifications URLSearchParams pour obtenir le même résultat de manière plus succincte. Voir la réponse intitulée " URLSearchParams " ci-dessous.

Code Spy
la source
131
Comment cette fonction gère-t-elle http://www.mysite.com/index.php?x=x1&x=x2&x=x3La valeur du champ xest ambiguë.
dpp
94
cela ne gère pas non plus les clés à valeurs multiples , qui sont également parfaitement légales.
hurrymaplelad
17
Pourquoi utiliseriez-vous une expression régulière pour cela?
Ry-
28
Pour une chaîne de requête de ?mykey=0&m.+key=1, appeler getParameterByName("m.+key")retournerait 0au lieu de 1. Vous devez échapper les métacaractères d'expression régulière nameavant de créer votre expression régulière. Et vous n'avez besoin d'appeler .replace()qu'une seule fois en utilisant l'indicateur global et en utilisant "\\$&"comme expression de remplacement. Vous devriez rechercher au location.searchlieu de location.href. Une réponse avec plus de 400 votes positifs devrait expliquer ces détails.
gilly3
7
Vous n'avez pas besoin de jQuery à cette fin ou à toute autre fin. Vous n'en avez juste PAS BESOIN.
gztomas
1708

Certaines des solutions affichées ici sont inefficaces. Répéter la recherche d'expressions régulières à chaque fois que le script doit accéder à un paramètre est complètement inutile, une seule fonction pour diviser les paramètres en un objet de style tableau associatif suffit. Si vous ne travaillez pas avec l'API HTML 5 History, cela n'est nécessaire qu'une fois par chargement de page. Les autres suggestions ici échouent également à décoder correctement l'URL.

var urlParams;
(window.onpopstate = function () {
    var match,
        pl     = /\+/g,  // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
        query  = window.location.search.substring(1);

    urlParams = {};
    while (match = search.exec(query))
       urlParams[decode(match[1])] = decode(match[2]);
})();

Exemple de chaîne de requête:

?i=main&mode=front&sid=de8d49b78a85a322c4155015fdce22c4&enc=+Hello%20&empty

Résultat:

 urlParams = {
    enc: " Hello ",
    i: "main",
    mode: "front",
    sid: "de8d49b78a85a322c4155015fdce22c4",
    empty: ""
}

alert(urlParams["mode"]);
// -> "front"

alert("empty" in urlParams);
// -> true

Cela pourrait facilement être amélioré pour gérer également les chaînes de requête de style tableau. Un exemple de ceci est ici , mais puisque les paramètres de style tableau ne sont pas définis dans RFC 3986, je ne polluerai pas cette réponse avec le code source. Pour ceux intéressés par une version "polluée", regardez la réponse de campbeln ci-dessous .

En outre, comme indiqué dans les commentaires, ;est un délimiteur légal pour les key=valuepaires. Cela nécessiterait une expression rationnelle plus compliquée à gérer ;ou &, ce qui, à mon avis, n'est pas nécessaire car il est rare qu'il ;soit utilisé et je dirais encore plus improbable que les deux soient utilisés. Si vous avez besoin de prendre en charge ;au lieu de &, échangez-les simplement dans l'expression régulière.


Si vous utilisez un langage de prétraitement côté serveur, vous pouvez utiliser ses fonctions natives JSON pour faire le gros du travail à votre place. Par exemple, en PHP, vous pouvez écrire:

<script>var urlParams = <?php echo json_encode($_GET, JSON_HEX_TAG);?>;</script>

Beaucoup plus simple!

MISE À JOUR

Une nouvelle capacité serait de récupérer les paramètres répétés comme suit myparam=1&myparam=2. Il n'y a pas de spécification , cependant, la plupart des approches actuelles suivent la génération d'un tableau.

myparam = ["1", "2"]

Voici donc l'approche pour le gérer:

let urlParams = {};
(window.onpopstate = function () {
    let match,
        pl = /\+/g,  // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) {
            return decodeURIComponent(s.replace(pl, " "));
        },
        query = window.location.search.substring(1);

    while (match = search.exec(query)) {
        if (decode(match[1]) in urlParams) {
            if (!Array.isArray(urlParams[decode(match[1])])) {
                urlParams[decode(match[1])] = [urlParams[decode(match[1])]];
            }
            urlParams[decode(match[1])].push(decode(match[2]));
        } else {
            urlParams[decode(match[1])] = decode(match[2]);
        }
    }
})();
Andy E
la source
11
si vous faites une application fortement ajaxée, alors vous utilisez peut-être le hachage (#) pour "activer le bouton de retour" ... dans ce cas, la chaîne de requête changerait tout le temps (voir comment Facebook le fait). .. bien que ces solutions ignorent les choses qui viennent après le # anways ...
Nick Franceschina
100
@Nick: Tout ce qui se trouve après le hachage réside dans la window.location.hashpropriété, qui est distincte de la window.location.searchpropriété. Si le hachage change, cela n'affecte pas du tout la chaîne de requête.
Andy E
27
N'oubliez pas qu'il ;s'agit d'un délimiteur légal pour les key=valuepaires GET . C'est rare, mais il faut 5 secondes pour l'implémenter.
alex
4
Pour être juste, aucun format spécifique pour la chaîne de requête n'est défini par RFC3986. ?a=b&c=dest classique et une recommandation du W3C pour les formulaires Web, mais la spécification URI définit simplement query = *( pchar / "/" / "?" ).
Matthew Gilliard
21
Pour ceux d'entre nous qui utilisent une configuration assez stricte de JSHint, échangez le while(match = search.exec(query))avecwhile((match = search.exec(query)) !== null)
craigts
1283

ES2015 (ES6)

getQueryStringParams = query => {
    return query
        ? (/^[?#]/.test(query) ? query.slice(1) : query)
            .split('&')
            .reduce((params, param) => {
                    let [key, value] = param.split('=');
                    params[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : '';
                    return params;
                }, {}
            )
        : {}
};

Sans jQuery

var qs = (function(a) {
    if (a == "") return {};
    var b = {};
    for (var i = 0; i < a.length; ++i)
    {
        var p=a[i].split('=', 2);
        if (p.length == 1)
            b[p[0]] = "";
        else
            b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
    }
    return b;
})(window.location.search.substr(1).split('&'));

Avec une URL comme ?topic=123&name=query+string, les éléments suivants seront renvoyés:

qs["topic"];    // 123
qs["name"];     // query string
qs["nothere"];  // undefined (object)

Méthode Google

En déchirant le code de Google, j'ai trouvé la méthode qu'ils utilisent: getUrlParameters

function (b) {
    var c = typeof b === "undefined";
    if (a !== h && c) return a;
    for (var d = {}, b = b || k[B][vb], e = b[p]("?"), f = b[p]("#"), b = (f === -1 ? b[Ya](e + 1) : [b[Ya](e + 1, f - e - 1), "&", b[Ya](f + 1)][K](""))[z]("&"), e = i.dd ? ia : unescape, f = 0, g = b[w]; f < g; ++f) {
        var l = b[f][p]("=");
        if (l !== -1) {
            var q = b[f][I](0, l),
                l = b[f][I](l + 1),
                l = l[Ca](/\+/g, " ");
            try {
                d[q] = e(l)
            } catch (A) {}
        }
    }
    c && (a = d);
    return d
}

C'est obscurci, mais c'est compréhensible. Cela ne fonctionne pas car certaines variables ne sont pas définies.

Ils commencent à chercher des paramètres sur l'url à ?partir du hash et aussi #. Ensuite, pour chaque paramètre, ils se divisent en signe égal b[f][p]("=")(qui ressemble indexOf, ils utilisent la position du caractère pour obtenir la clé / valeur). Après l'avoir divisé, ils vérifient si le paramètre a une valeur ou non, si c'est le cas, ils stockent la valeur de d, sinon ils continuent simplement.

Au final, l'objet dest retourné, gérant l'échappement et le +signe. Cet objet est comme le mien, il a le même comportement.


Ma méthode en tant que plugin jQuery

(function($) {
    $.QueryString = (function(paramsArray) {
        let params = {};

        for (let i = 0; i < paramsArray.length; ++i)
        {
            let param = paramsArray[i]
                .split('=', 2);

            if (param.length !== 2)
                continue;

            params[param[0]] = decodeURIComponent(param[1].replace(/\+/g, " "));
        }

        return params;
    })(window.location.search.substr(1).split('&'))
})(jQuery);

Usage

//Get a param
$.QueryString.param
//-or-
$.QueryString["param"]
//This outputs something like...
//"val"

//Get all params as object
$.QueryString
//This outputs something like...
//Object { param: "val", param2: "val" }

//Set a param (only in the $.QueryString object, doesn't affect the browser's querystring)
$.QueryString.param = "newvalue"
//This doesn't output anything, it just updates the $.QueryString object

//Convert object into string suitable for url a querystring (Requires jQuery)
$.param($.QueryString)
//This outputs something like...
//"param=newvalue&param2=val"

//Update the url/querystring in the browser's location bar with the $.QueryString object
history.replaceState({}, '', "?" + $.param($.QueryString));
//-or-
history.pushState({}, '', "?" + $.param($.QueryString));

Test de performance (méthode fractionnée contre méthode regex) ( jsPerf )

Code de préparation: déclaration des méthodes

Code de test fractionné

var qs = window.GetQueryString(query);

var search = qs["q"];
var value = qs["value"];
var undef = qs["undefinedstring"];

Code de test Regex

var search = window.getParameterByName("q");
var value = window.getParameterByName("value");
var undef = window.getParameterByName("undefinedstring");

Test dans Firefox 4.0 x86 sur Windows Server 2008 R2 / 7 x64

  • Méthode de partage : 144,780 ± 2,17% plus rapide
  • Méthode regex: 13 891 ± 0,85% | 90% plus lent
BrunoLM
la source
1
C'est aussi une bonne approche, le fractionnement de chaînes au lieu d'utiliser des expressions régulières. Il y a quelques choses qui méritent d'être soulignées, cependant :-) 1. unescapeest une fonction obsolète et est remplacée par decodeURIComponent(), notez qu'aucune de ces fonctions ne décodera correctement a +en caractère espace. 2. Vous devez déclarer le résultat en tant qu'objet plutôt qu'en tant que tableau, car JavaScript n'a pas de tableaux associatifs en soi et le tableau que vous déclarez est traité comme un objet en lui affectant de toute façon des propriétés nommées.
Andy E
55
Curieux de savoir pourquoi vous en feriez un plugin jQuery alors qu'il n'a pas de code spécifique à jQuery?
zachleat
63
@zachleat si vous n'avez pas de framework, vos fonctions seront simplement réparties dans votre code. Si vous étendez jQuery, vous aurez une portée pour vos fonctions, il ne flottera pas quelque part dans votre code. Je pense que c'est la seule raison.
BrunoLM
6
Voici la version jQuery modifiée pour passer JSLint (au moins la cible semi-mobile de JSLint.com le 2011-06-15). Surtout juste déplacer des choses pour apaiser The Crockford.
patridge
3
Comme @BenjaminGruenbaum a plaisanté, moi aussi, je ne vois pas vraiment l'intérêt de comparer les performances de l'analyse d'URL. Si cela a été transformé en un module JavaScript isomorphe qui pourrait être appelé depuis Node pour, par exemple, analyser les journaux, alors oui. Mais son utilisation pour extraire les paramètres d'URL window.locationrend tout problème de performance inutile, étant donné que le client naviguant vers l'URL est beaucoup, beaucoup plus cher.
Dan Dascalescu
659

Version améliorée de la réponse d' Artem Barger :

function getParameterByName(name) {
    var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
    return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}

Pour plus d'informations sur l'amélioration, voir: http://james.padolsey.com/javascript/bujs-1-getparameterbyname/

James
la source
23
Si vous vouliez le raccourcir un peu plus, vous pourriez supprimer le conditionnel ternaire et le remplacer par un peu de court-circuit sur cette dernière ligne - return match && decodeURIComponent(match[1].replace(/\+/g, ' '));.
Andy E
Il retourne nullsi le paramètre n'est pas suivi de '='. Vous pouvez ajouter un préfixe if (!RegExp('[?&]'+name+'(&.*)?$').exec(window.location.search)) return false;pour le faire revenir boolean falsesi le paramètre n'est pas là du tout.
commonpike
9
J'utiliserais le newpréfixe lors de la création de l'expression régulière:var match = new RegExp('...
Patrick Berkeley
2
Bogue IE11: IE décide d'ajouter la valeur renvoyée avec le caractère ascii 8206 (hex: 200E - le "caractère de gauche à droite"). J'ai perdu plus de 6 heures à trouver ça! ventilation thérapeutique .... pour réparer, virer jusqu'au bout de la dernière ligne:.replace('\u200E', '')
JayRO-GreyBeard
Dans Chrome sur un Mac au moins (peut-être d'autres navigateurs aussi), la dernière valeur était ajoutée avec un '/'. J'ai donc modifié l'expression régulière pour l'ignorer. var results = new RegExp('[\\?&]' + name + '=([^&#/]*)').exec(url);
CaseyB
594

URLSearchParams

Firefox 44+, Opera 36+, Edge 17+, Safari 10.3+ et Chrome 49+ prennent en charge l' API URLSearchParams :

Il existe un polyfill URLSearchParams suggéré par Google pour les versions stables d'IE.

Il n'est pas normalisé par le W3C , mais c'est un niveau de vie par WhatWG .

Vous pouvez l'utiliser sur location:

let params = new URLSearchParams(location.search);

ou

let params = (new URL(location)).searchParams;

Ou bien sûr sur n'importe quelle URL:

let url = new URL('https://example.com?foo=1&bar=2');
let params = new URLSearchParams(url.search);

Vous pouvez également obtenir des paramètres en utilisant une .searchParamspropriété abrégée sur l'objet URL, comme ceci:

let params = new URL('https://example.com?foo=1&bar=2').searchParams;
params.get('foo'); // "1"
params.get('bar'); // "2" 

Vous lisez / paramètres fixés par la get(KEY), set(KEY, VALUE), append(KEY, VALUE)API. Vous pouvez également parcourir toutes les valeurs for (let p of params) {}.

Une implémentation de référence et un exemple de page sont disponibles pour l'audit et les tests.

Paul Sweatte
la source
Ces deux downvoters ont probablement manqué (comme je viens de le faire) le fait que vous devez utiliser .getau lieu de simplement.
Nakilon
20
Vous n'avez pas vraiment besoin de l' slice(1)allumer .search, vous pouvez l'utiliser directement. URLSearchParams peut gérer le début ?.
Jason C
URLSearchParamsn'est pas bon car il ne renvoie pas les valeurs réelles des paramètres d'une URL.
Melab
Cela new URL('https://example.com?foo=1&bar=2') ne fonctionne pas pour l'url Androidfile:///android_asset/...
shah
@Melab c'est toujours bon car il fournit une API simple pour toutes les expressions bizarres dans les autres réponses ici. Mais cela me fait aussi bizarre que id ne fasse pas window.location.search par défaut et qu'il n'y ait aucun moyen de mettre à jour l'url actuelle incluse.
Damon
400

Juste une autre recommandation. Le plugin Purl permet de récupérer toutes les parties de l'URL, y compris l'ancre, l'hôte, etc.

Il peut être utilisé avec ou sans jQuery.

L'utilisation est très simple et cool:

var url = $.url('http://allmarkedup.com/folder/dir/index.html?item=value'); // jQuery version
var url = purl('http://allmarkedup.com/folder/dir/index.html?item=value'); // plain JS version
url.attr('protocol'); // returns 'http'
url.attr('path'); // returns '/folder/dir/index.html'

Cependant, depuis le 11 novembre 2014, Purl n'est plus géré et l'auteur recommande d'utiliser plutôt URI.js. Le plugin jQuery est différent en ce qu'il se concentre sur les éléments - pour une utilisation avec des chaînes, utilisez simplement URIdirectement, avec ou sans jQuery. Un code similaire ressemblerait à cela, des documents plus complets ici :

var url = new URI('http://allmarkedup.com/folder/dir/index.html?item=value'); // plain JS version
url.protocol(); // returns 'http'
url.path(); // returns '/folder/dir/index.html'
AlfaTeK
la source
7
Au moment de l'écriture, le lien n'est plus maintenu et le responsable précédent suggère uri.js
Dan Pantry
238

tl; dr

Une solution rapide et complète , qui gère les clés à plusieurs valeurs et les caractères encodés .

var qd = {};
if (location.search) location.search.substr(1).split("&").forEach(function(item) {var s = item.split("="), k = s[0], v = s[1] && decodeURIComponent(s[1]); (qd[k] = qd[k] || []).push(v)})

//using ES6   (23 characters cooler)
var qd = {};
if (location.search) location.search.substr(1).split`&`.forEach(item => {let [k,v] = item.split`=`; v = v && decodeURIComponent(v); (qd[k] = qd[k] || []).push(v)})
Multi-doublé:
var qd = {};
if (location.search) location.search.substr(1).split("&").forEach(function(item) {
    var s = item.split("="),
        k = s[0],
        v = s[1] && decodeURIComponent(s[1]); //  null-coalescing / short-circuit
    //(k in qd) ? qd[k].push(v) : qd[k] = [v]
    (qd[k] = qd[k] || []).push(v) // null-coalescing / short-circuit
})

Qu'est-ce que tout ce code ...
"coalescence nulle" , évaluation des courts-circuits
ES6 Affectations de destruction , fonctions fléchées , chaînes de modèle

Exemple:
"?a=1&b=0&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"
> qd
a: ["1", "5", "t e x t"]
b: ["0"]
c: ["3"]
d: [undefined]
e: [undefined, "http://w3schools.com/my test.asp?name=ståle&car=saab"]

> qd.a[1]    // "5"
> qd["a"][1] // "5"



En savoir plus ... sur la solution JavaScript Vanilla.

Pour accéder à différentes parties d'une URL, utilisez location.(search|hash)

Solution la plus simple (factice)

var queryDict = {};
location.search.substr(1).split("&").forEach(function(item) {queryDict[item.split("=")[0]] = item.split("=")[1]})
  • Gère les clés vides correctement.
  • Remplace les touches multiples avec la dernière valeur trouvée.
"?a=1&b=0&c=3&d&e&a=5"
> queryDict
a: "5"
b: "0"
c: "3"
d: undefined
e: undefined

Clés à valeurs multiples

Vérification simple des clés (item in dict) ? dict.item.push(val) : dict.item = [val]

var qd = {};
location.search.substr(1).split("&").forEach(function(item) {(item.split("=")[0] in qd) ? qd[item.split("=")[0]].push(item.split("=")[1]) : qd[item.split("=")[0]] = [item.split("=")[1]]})
  • Renvoie maintenant des tableaux à la place.
  • Accéder aux valeurs par qd.key[index]ouqd[key][index]
> qd
a: ["1", "5"]
b: ["0"]
c: ["3"]
d: [undefined]
e: [undefined]

Caractères codés?

Utilisez decodeURIComponent()pour la deuxième ou les deux divisions.

var qd = {};
location.search.substr(1).split("&").forEach(function(item) {var k = item.split("=")[0], v = decodeURIComponent(item.split("=")[1]); (k in qd) ? qd[k].push(v) : qd[k] = [v]})
Exemple:
"?a=1&b=0&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"
> qd
a: ["1", "5", "t e x t"]
b: ["0"]
c: ["3"]
d: ["undefined"]  // decodeURIComponent(undefined) returns "undefined" !!!*
e: ["undefined", "http://w3schools.com/my test.asp?name=ståle&car=saab"]



Des commentaires

* !!! Veuillez noter que cela decodeURIComponent(undefined)renvoie une chaîne "undefined". La solution réside dans une utilisation simple de &&, ce qui garantit qu'il decodeURIComponent()n'est pas appelé sur des valeurs non définies. (Voir la "solution complète" en haut.)

v = v && decodeURIComponent(v);


Si la chaîne de requête est vide ( location.search == ""), le résultat est quelque peu trompeur qd == {"": undefined}. Il est suggéré de vérifier la chaîne de requête avant de lancer la fonction d'analyse comme:

if (location.search) location.search.substr(1).split("&").forEach(...)
Qwerty
la source
1
Agréable. La seule chose que je changerais - c'est qu'il n'y a pas plus d'une valeur pour une clé, il n'est pas nécessaire qu'elle soit un tableau. N'utilisez un tableau que s'il existe plusieurs valeurs par clé.
Pavel Nikolov
2
@PavelNikolov Je pense que cela introduirait des difficultés à obtenir parfois un tableau et parfois une valeur. Vous devrez d'abord le vérifier, maintenant vous ne vérifiez que la longueur, car vous utiliserez de toute façon des cycles pour récupérer ces valeurs. Cela devait également être la solution la plus simple, mais fonctionnelle, ici.
Qwerty
@katsh Oui, en effet, cela fonctionne dans> = IE9, cependant, vous pouvez apprendre à votre processeur javascript array.forEach()en injectant du code au début de votre script. voir Polyfill developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Qwerty
1
Aplati un peu pour la lisibilité, transformé en fonction, et réutilisation de l'appel fractionné: function parseQueryString () {var qd = {}; location.search.substr (1) .split ("&"). forEach (function (item) {var parts = item.split ("="); var k = parts [0]; var v = decodeURIComponent (parts [ 1]); (k dans qd)? Qd [k] .push (v): qd [k] = [v,]}); return qd; }
Casey
1
decodeDocumentURI (undefined) renvoie "undefined" au lieu d'undefined. Un patch fonctionnel mais pas très élégant: var qd = {}; location.search.substr(1).split("&").forEach( function(item) { var s = item.split("="), k = s[0], v; if(s.length>1) v = decodeURIComponent(s[1]); (k in qd) ? qd[k].push(v) : qd[k] = [v] })
loop
218

Roshambo sur snipplr.com dispose d'un script simple pour y parvenir décrit dans Obtenir les paramètres d'URL avec jQuery | Amélioré . Avec son script, vous obtenez également facilement les paramètres que vous souhaitez.

Voici l'essentiel:

$.urlParam = function(name, url) {
    if (!url) {
     url = window.location.href;
    }
    var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(url);
    if (!results) { 
        return undefined;
    }
    return results[1] || undefined;
}

Ensuite, obtenez simplement vos paramètres à partir de la chaîne de requête.

Donc, si la chaîne URL / requête était xyz.com/index.html?lang=de.

Appelez simplement var langval = $.urlParam('lang');, et vous l'avez.

UZBEKJON a également un excellent article sur ce sujet, Obtenez les paramètres et valeurs d'URL avec jQuery .

brandonjp
la source
13
avec jQuery semble signifier l'espace de noms de la fonction à l'objet jQuery. Aussi, pourquoi la valeur n'est-elle pas valide 0? Bien sûr, je pourrais utiliser un contrôle d'égalité strict, mais ne devrait-il pas en être ainsi null?
alex
D'accord. Cela fonctionne comme une référence de variable javascript normale de cette façon (sauf peut-être qu'un retour non défini serait plus précis).
Isochronous
'nom' n'est pas correctement échappé, il est juste directement injecté dans RegExp. Cela échoue. Comme d'autres l'ont dit, il est incroyable que ces réponses réinventent la roue et obtiennent autant de votes, alors que cela devrait être implémenté dans une bibliothèque bien testée.
Triynko
167

Si vous utilisez jQuery, vous pouvez utiliser une bibliothèque, telle que jQuery BBQ: Back Button & Query Library .

... jQuery BBQ fournit une .deparam()méthode complète , ainsi que la gestion de l'état de hachage et des méthodes utilitaires d'analyse et de fusion de chaînes de fragments / requêtes.

Edit: Ajout de Deparam Exemple:

 var DeparamExample = function() {
            var params = $.deparam.querystring();

            //nameofparam is the name of a param from url
            //code below will get param if ajax refresh with hash
            if (typeof params.nameofparam == 'undefined') {
                params = jQuery.deparam.fragment(window.location.href);
            }
            
            if (typeof params.nameofparam != 'undefined') {
                var paramValue = params.nameofparam.toString();
                  
            }
        };

Si vous souhaitez simplement utiliser JavaScript, vous pouvez utiliser ...

var getParamValue = (function() {
    var params;
    var resetParams = function() {
            var query = window.location.search;
            var regex = /[?&;](.+?)=([^&;]+)/g;
            var match;

            params = {};

            if (query) {
                while (match = regex.exec(query)) {
                    params[match[1]] = decodeURIComponent(match[2]);
                }
            }    
        };

    window.addEventListener
    && window.addEventListener('popstate', resetParams);

    resetParams();

    return function(param) {
        return params.hasOwnProperty(param) ? params[param] : null;
    }

})();​

En raison de la nouvelle API d'historique HTML et spécifiquement history.pushState()et history.replaceState(), l'URL peut changer, ce qui invalidera le cache des paramètres et leurs valeurs.

Cette version mettra à jour son cache interne de paramètres à chaque changement d'historique.

alex
la source
100

Utilisez simplement deux divisions :

function get(n) {
    var half = location.search.split(n + '=')[1];
    return half !== undefined ? decodeURIComponent(half.split('&')[0]) : null;
}

Je lisais toutes les réponses précédentes et plus complètes. Mais je pense que c'est la méthode la plus simple et la plus rapide. Vous pouvez vérifier dans ce benchmark jsPerf

Pour résoudre le problème dans le commentaire de Rup, ajoutez un fractionnement conditionnel en remplaçant la première ligne par les deux ci-dessous. Mais la précision absolue signifie qu'il est maintenant plus lent que regexp (voir jsPerf ).

function get(n) {
    var half = location.search.split('&' + n + '=')[1];
    if (!half) half = location.search.split('?' + n + '=')[1];
    return half !== undefined ? decodeURIComponent(half.split('&')[0]) : null;
}

Donc, si vous savez que vous ne rencontrerez pas le contre-cas de Rup, cela gagne. Sinon, regexp.

Ou si vous contrôlez la chaîne de requête et pouvez garantir qu'une valeur que vous essayez d'obtenir ne contiendra jamais de caractères encodés URL (les avoir dans une valeur serait une mauvaise idée) - vous pouvez utiliser la version suivante légèrement plus simplifiée et lisible de la 1ère option:

    function getQueryStringValueByName(name) {
        var queryStringFromStartOfValue = location.search.split(name + '=')[1];
         return queryStringFromStartOfValue !== undefined ? queryStringFromStartOfValue.split('&')[0] : null;
Martin Borthiry
la source
7
Très propre! Cela ne fonctionnera pas si vous avez une valeur antérieure avec un nom de clé qui se termine par celui que vous voulez, par exemple get('value')sur http://the-url?oldvalue=1&value=2.
Rup
3
Cependant, si vous savez que le nom du paramètre est attendu, ce sera l'approche la plus rapide.
Martin Borthiry
Modifié: si vous testez juste que halfc'est vrai, cela retourne null pour un paramètre vide comme ?param=. Il doit retourner la chaîne vide dans ce cas, et la vérification half !== undefinedrésout cela.
philh
Cool! J'ai fait un one-liner:function get(param){return decodeURIComponent((location.search.split(param+'=')[1]||'').split('&')[0])}
niutech
J'ai dû changer la deuxième ligne pour la return half !== undefined ? decodeURIComponent(half[1].split('&')[0]) : null;faire fonctionner
divillysausages
95

Voici ma tentative pour faire de l'excellente solution d'Andy E un plugin jQuery à part entière:

;(function ($) {
    $.extend({      
        getQueryString: function (name) {           
            function parseParams() {
                var params = {},
                    e,
                    a = /\+/g,  // Regex for replacing addition symbol with a space
                    r = /([^&=]+)=?([^&]*)/g,
                    d = function (s) { return decodeURIComponent(s.replace(a, " ")); },
                    q = window.location.search.substring(1);

                while (e = r.exec(q))
                    params[d(e[1])] = d(e[2]);

                return params;
            }

            if (!this.queryStringParams)
                this.queryStringParams = parseParams(); 

            return this.queryStringParams[name];
        }
    });
})(jQuery);

La syntaxe est:

var someVar = $.getQueryString('myParam');

Le meilleur des deux mondes!

Ryan Phelan
la source
76

Si vous faites plus de manipulation d'URL que d'analyser simplement la chaîne de requête, vous pouvez trouver URI.js utile. Il s'agit d'une bibliothèque pour manipuler les URL - et est livré avec toutes les cloches et les sifflets. (Désolé pour l'auto-publicité ici)

pour convertir votre chaîne de requête en carte:

var data = URI('?foo=bar&bar=baz&foo=world').query(true);
data == {
  "foo": ["bar", "world"],
  "bar": "baz"
}

(URI.js aussi « fixe » mauvais querystrings aiment ?&foo&&bar=baz&à ?foo&bar=baz)

rodneyrehm
la source
// chargement de src / URI.fragmentURI.js requis
JoeB
1
+1 URI.js est un super petit plugin. Vous pouvez également faire var data = URI.parseQuery('?foo=bar&bar=baz&foo=world');pour le même résultat ( docs ).
Yarin
62

J'aime la solution de Ryan Phelan . Mais je ne vois aucun intérêt à étendre jQuery pour cela? Il n'y a aucune utilisation de la fonctionnalité jQuery.

D'un autre côté, j'aime la fonction intégrée dans Google Chrome: window.location.getParameter.

Alors pourquoi ne pas l'utiliser? D'accord, les autres navigateurs n'en ont pas. Créons donc cette fonction si elle n'existe pas:

if (!window.location.getParameter ) {
  window.location.getParameter = function(key) {
    function parseParams() {
        var params = {},
            e,
            a = /\+/g,  // Regex for replacing addition symbol with a space
            r = /([^&=]+)=?([^&]*)/g,
            d = function (s) { return decodeURIComponent(s.replace(a, " ")); },
            q = window.location.search.substring(1);

        while (e = r.exec(q))
            params[d(e[1])] = d(e[2]);

        return params;
    }

    if (!this.queryStringParams)
        this.queryStringParams = parseParams(); 

    return this.queryStringParams[key];
  };
}

Cette fonction est plus ou moins de Ryan Phelan, mais elle est enveloppée différemment: nom clair et aucune dépendance des autres bibliothèques javascript. Plus d'informations sur cette fonction sur mon blog .

Anatoly Mironov
la source
3
Il semble que window.location.getParameter () ait été supprimé de Chrome.
mhenry1384
54

Voici un moyen rapide d'obtenir un objet similaire au tableau PHP $ _GET :

function get_query(){
    var url = location.search;
    var qs = url.substring(url.indexOf('?') + 1).split('&');
    for(var i = 0, result = {}; i < qs.length; i++){
        qs[i] = qs[i].split('=');
        result[qs[i][0]] = decodeURIComponent(qs[i][1]);
    }
    return result;
}

Usage:

var $_GET = get_query();

Pour la chaîne de requête, x=5&y&z=hello&x=6cela renvoie l'objet:

{
  x: "6",
  y: undefined,
  z: "hello"
}
Paulpro
la source
si vous en avez besoin en tant que plugin jQuery, le voici: (function($) { $.extend({ get_query: function (name) { var url = location.href; var qs = url.substring(url.indexOf('?') + 1).split('&'); for(var i = 0, result = {}; i < qs.length; i++){ qs[i] = qs[i].split('='); result[qs[i][0]] = qs[i][1]; } return result; } }); })(jQuery);et utilisez comme ceci:$.get_query()
tim
Merci. J'ai aussi fini par l'utiliser. J'ai ajouté ceci avant votre déclaration de retour: si (param) renvoie le résultat [param], de cette façon, je peux également faire get_query ('foo') si nécessaire
sqram
1
Ne fonctionne pas si vous avez des hachages. Par exemple: test.aspx? Test = t1 # par défaut . Retournera {test: "t1 # default"} et j'attends {test: "t1"}
Bogdan M.
@BogdanM: en effet. location.hrefdevrait être remplacé par location.search.
Dan Dascalescu
53

Restez simple avec du code JavaScript simple:

function qs(key) {
    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[key];
}

Appelez-le de n'importe où dans le code JavaScript:

var result = qs('someKey');
sagivo
la source
1
Je pense que vous faites quelque chose de similaire à moi, mais je pense que mon approche est BEAUCOUP plus simple stackoverflow.com/a/21152762/985454
Qwerty
Permettez-moi de vous présenter (roulement de tambour s'il vous plaît) window.location.search !
ErikE
46

Ce sont toutes d'excellentes réponses, mais j'avais besoin de quelque chose d'un peu plus robuste, et j'ai pensé que vous aimeriez tous avoir ce que j'ai créé.

Il s'agit d'une méthode de bibliothèque simple qui effectue la dissection et la manipulation des paramètres d'URL. La méthode statique a les sous-méthodes suivantes qui peuvent être appelées sur l'URL du sujet:

  • getHost
  • getPath
  • getHash
  • setHash
  • getParams
  • getQuery
  • setParam
  • getParam
  • hasParam
  • removeParam

Exemple:

URLParser(url).getParam('myparam1')

var url = "http://www.test.com/folder/mypage.html?myparam1=1&myparam2=2#something";

function URLParser(u){
    var path="",query="",hash="",params;
    if(u.indexOf("#") > 0){
        hash = u.substr(u.indexOf("#") + 1);
        u = u.substr(0 , u.indexOf("#"));
    }
    if(u.indexOf("?") > 0){
        path = u.substr(0 , u.indexOf("?"));
        query = u.substr(u.indexOf("?") + 1);
        params= query.split('&');
    }else
        path = u;
    return {
        getHost: function(){
            var hostexp = /\/\/([\w.-]*)/;
            var match = hostexp.exec(path);
            if (match != null && match.length > 1)
                return match[1];
            return "";
        },
        getPath: function(){
            var pathexp = /\/\/[\w.-]*(?:\/([^?]*))/;
            var match = pathexp.exec(path);
            if (match != null && match.length > 1)
                return match[1];
            return "";
        },
        getHash: function(){
            return hash;
        },
        getParams: function(){
            return params
        },
        getQuery: function(){
            return query;
        },
        setHash: function(value){
            if(query.length > 0)
                query = "?" + query;
            if(value.length > 0)
                query = query + "#" + value;
            return path + query;
        },
        setParam: function(name, value){
            if(!params){
                params= new Array();
            }
            params.push(name + '=' + value);
            for (var i = 0; i < params.length; i++) {
                if(query.length > 0)
                    query += "&";
                query += params[i];
            }
            if(query.length > 0)
                query = "?" + query;
            if(hash.length > 0)
                query = query + "#" + hash;
            return path + query;
        },
        getParam: function(name){
            if(params){
                for (var i = 0; i < params.length; i++) {
                    var pair = params[i].split('=');
                    if (decodeURIComponent(pair[0]) == name)
                        return decodeURIComponent(pair[1]);
                }
            }
            console.log('Query variable %s not found', name);
        },
        hasParam: function(name){
            if(params){
                for (var i = 0; i < params.length; i++) {
                    var pair = params[i].split('=');
                    if (decodeURIComponent(pair[0]) == name)
                        return true;
                }
            }
            console.log('Query variable %s not found', name);
        },
        removeParam: function(name){
            query = "";
            if(params){
                var newparams = new Array();
                for (var i = 0;i < params.length;i++) {
                    var pair = params[i].split('=');
                    if (decodeURIComponent(pair[0]) != name)
                          newparams .push(params[i]);
                }
                params = newparams;
                for (var i = 0; i < params.length; i++) {
                    if(query.length > 0)
                        query += "&";
                    query += params[i];
                }
            }
            if(query.length > 0)
                query = "?" + query;
            if(hash.length > 0)
                query = query + "#" + hash;
            return path + query;
        },
    }
}


document.write("Host: " + URLParser(url).getHost() + '<br>');
document.write("Path: " + URLParser(url).getPath() + '<br>');
document.write("Query: " + URLParser(url).getQuery() + '<br>');
document.write("Hash: " + URLParser(url).getHash() + '<br>');
document.write("Params Array: " + URLParser(url).getParams() + '<br>');
document.write("Param: " + URLParser(url).getParam('myparam1') + '<br>');
document.write("Has Param: " + URLParser(url).hasParam('myparam1') + '<br>');

document.write(url + '<br>');

// Remove the first parameter
url = URLParser(url).removeParam('myparam1');
document.write(url + ' - Remove the first parameter<br>');

// Add a third parameter
url = URLParser(url).setParam('myparam3',3);
document.write(url + ' - Add a third parameter<br>');

// Remove the second parameter
url = URLParser(url).removeParam('myparam2');
document.write(url + ' - Remove the second parameter<br>');

// Add a hash
url = URLParser(url).setHash('newhash');
document.write(url + ' - Set Hash<br>');

// Remove the last parameter
url = URLParser(url).removeParam('myparam3');
document.write(url + ' - Remove the last parameter<br>');

// Remove a parameter that doesn't exist
url = URLParser(url).removeParam('myparam3');
document.write(url + ' - Remove a parameter that doesn\"t exist<br>');
meagar
la source
44

Du MDN :

function loadPageVar (sVar) {
  return unescape(window.location.search.replace(new RegExp("^(?:.*[&\\?]" + escape(sVar).replace(/[\.\+\*]/g, "\\$&") + "(?:\\=([^&]*))?)?.*$", "i"), "$1"));
}

alert(loadPageVar("name"));
orip
la source
39

Code golf:

var a = location.search&&location.search.substr(1).replace(/\+/gi," ").split("&");
for (var i in a) {
    var s = a[i].split("=");
    a[i]  = a[unescape(s[0])] = unescape(s[1]);
}

Affichez-le!

for (i in a) {
    document.write(i + ":" + a[i] + "<br/>");   
};

Sur mon Mac: test.htm?i=can&has=cheezburgeraffiche

0:can
1:cheezburger
i:can
has:cheezburger
shanimal
la source
9
J'adore votre réponse, en particulier la compacité du script, mais vous devriez probablement utiliser decodeURIComponent. Voir xkr.us/articles/javascript/encode-compare et stackoverflow.com/questions/619323/…
pluckyglen
39

J'utilise beaucoup d'expressions régulières, mais pas pour ça.

Il me semble plus facile et plus efficace de lire la chaîne de requête une fois dans mon application et de construire un objet à partir de toutes les paires clé / valeur comme:

var search = function() {
  var s = window.location.search.substr(1),
    p = s.split(/\&/), l = p.length, kv, r = {};
  if (l === 0) {return false;}
  while (l--) {
    kv = p[l].split(/\=/);
    r[kv[0]] = decodeURIComponent(kv[1] || '') || true;
  }
  return r;
}();

Pour une URL comme http://domain.com?param1=val1&param2=val2vous pouvez obtenir leur valeur plus tard dans votre code au fur search.param1et à mesure search.param2.

Mic
la source
38
function GET() {
        var data = [];
        for(x = 0; x < arguments.length; ++x)
            data.push(location.href.match(new RegExp("/\?".concat(arguments[x],"=","([^\n&]*)")))[1])
                return data;
    }


example:
data = GET("id","name","foo");
query string : ?id=3&name=jet&foo=b
returns:
    data[0] // 3
    data[1] // jet
    data[2] // b
or
    alert(GET("id")[0]) // return 3
Jet
la source
5
Il s'agit d'une approche intéressante, renvoyant un tableau contenant des valeurs à partir des paramètres spécifiés. Il a au moins un problème - pas correctement le décodage d'URL des valeurs, et il devrait également encoder les noms de paramètres utilisés en correspondance. Il fonctionnera cependant sur des chaînes de requête simples dans sa forme actuelle. ps n'oubliez pas d'utiliser le mot-clé var lors de la déclaration des variables dans les instructions for .
Andy E
38

La méthode Roshambo jQuery ne s'occupait pas de décoder l'URL

http://snipplr.com/view/26662/get-url-parameters-with-jquery--improved/

Je viens d'ajouter cette capacité également lors de l'ajout dans la déclaration de retour

return decodeURIComponent(results[1].replace(/\+/g, " ")) || 0;

Vous pouvez maintenant trouver l'essentiel mis à jour:

$.urlParam = function(name){
var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
if (!results) { return 0; }
return decodeURIComponent(results[1].replace(/\+/g, " ")) || 0;
}
Mohammed Arif
la source
36

J'aime celui-ci (tiré de jquery-howto.blogspot.co.uk):

// get an array with all querystring values
// example: var valor = getUrlVars()["valor"];
function getUrlVars() {
    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;
}

Fonctionne très bien pour moi.

Tomamais
la source
36

Voici ma modification de cette excellente réponse - avec une possibilité supplémentaire d'analyser les chaînes de requête avec des clés sans valeurs.

var url = 'http://sb.com/reg/step1?param';
var qs = (function(a) {
    if (a == "") return {};
    var b = {};
    for (var i = 0; i < a.length; ++i) {
        var p=a[i].split('=', 2);
        if (p[1]) p[1] = decodeURIComponent(p[1].replace(/\+/g, " "));
        b[p[0]] = p[1];
    }
    return b;
})((url.split('?'))[1].split('&'));

IMPORTANT!Le paramètre de cette fonction dans la dernière ligne est différent. C'est juste un exemple de la façon dont on peut lui passer une URL arbitraire. Vous pouvez utiliser la dernière ligne de la réponse de Bruno pour analyser l'URL actuelle.

Alors qu'est-ce qui a changé exactement? Avec l'url, les http://sb.com/reg/step1?param=résultats seront les mêmes. Mais avec l'URL, http://sb.com/reg/step1?paramla solution de Bruno renvoie un objet sans clé, tandis que la mienne renvoie un objet avec clé paramet undefinedvaleur.

skaurus
la source
34

J'avais besoin d'un objet de la chaîne de requête et je déteste beaucoup de code. Ce n'est peut-être pas le plus robuste de l'univers, mais ce ne sont que quelques lignes de code.

var q = {};
location.href.split('?')[1].split('&').forEach(function(i){
    q[i.split('=')[0]]=i.split('=')[1];
});

Une URL comme this.htm?hello=world&foo=barva créer:

{hello:'world', foo:'bar'}
tim
la source
4
Soigné. Selon Mozilla, cependant, forEach ne fonctionne pas sur IE7 ou 8 et je soupçonne que cela tombera s'il n'y a aucune chaîne de requête. Une amélioration minimale qui couvrirait plus de cas serait decodeURIComponentla valeur que vous stockez - et sans doute la clé également, mais vous êtes moins susceptible d'utiliser des chaînes impaires à cet égard.
Rup
1
Agréable et simple. Ne gère pas non plus les paramètres du tableau, ?a&b&cmais c'est vraiment très lisible (et d'ailleurs similaire à ma première idée). De plus, splitc'est redondant, mais j'ai des poissons plus performants à faire frire que de diviser deux fois une chaîne de 10 caractères.
cod3monk3y
1
lorsque querystring est "? hello = world & one = a = b & two = 2", puis lorsque vous saisissez la valeur de "un", vous obtenez uniquement la partie avant le premier "=" dans la valeur. sa valeur devrait être 'a = b' mais vous obtenez seulement 'a' parce que vous divisez 'one = a = b' on '='. c'est tout simplement bogué. : ((
Shawn Kovac
2
J'utiliserais location.search.substr(1)au lieu de location.href.split('?')[1]pour éviter de prendre hash ( #anchor) avec le dernier paramètre de requête.
mlt
Oui, permettez-moi également de vous présenter location.search!
ErikE
32

Voici une version étendue de la version liée de "Handle array-style query strings" d'Andy E. Correction d'un bug ( ?key=1&key[]=2&key[]=3; 1est perdu et remplacé par [2,3]), a apporté quelques améliorations mineures aux performances (re-décodage des valeurs, recalcul de la position "[", etc.) et a ajouté un certain nombre d'améliorations (fonctionnalisées, prise en charge ?key=1&key=2, prise en charge des ;délimiteurs) . J'ai laissé les variables énormément courtes, mais j'ai ajouté de nombreux commentaires pour les rendre lisibles (oh, et j'ai réutilisé vdans les fonctions locales, désolé si cela prête à confusion;).

Il gérera la chaîne de requête suivante ...

? test = Bonjour & personne = neek & personne [] = jeff & personne [] = jim & personne [extra] = john & test3 & nocache = 1398914891264

... ce qui en fait un objet qui ressemble à ...

{
    "test": "Hello",
    "person": {
        "0": "neek",
        "1": "jeff",
        "2": "jim",
        "length": 3,
        "extra": "john"
    },
    "test3": "",
    "nocache": "1398914891264"
}

Comme vous pouvez le voir ci-dessus, cette version gère une certaine mesure des tableaux "malformés", c'est-à-dire - person=neek&person[]=jeff&person[]=jimou alors person=neek&person=jeff&person=jimque la clé est identifiable et valide (au moins dans NameValueCollection.Add de dotNet ):

Si la clé spécifiée existe déjà dans l'instance NameValueCollection cible, la valeur spécifiée est ajoutée à la liste de valeurs séparée par des virgules existante sous la forme "valeur1, valeur2, valeur3".

Il semble que le jury soit un peu sur les touches répétées car il n'y a aucune spécification. Dans ce cas, plusieurs clés sont stockées dans un (faux) tableau. Mais notez que je ne traite pas les valeurs basées sur des virgules dans des tableaux.

Le code:

getQueryStringKey = function(key) {
    return getQueryStringAsObject()[key];
};


getQueryStringAsObject = function() {
    var b, cv, e, k, ma, sk, v, r = {},
        d = function (v) { return decodeURIComponent(v).replace(/\+/g, " "); }, //# d(ecode) the v(alue)
        q = window.location.search.substring(1), //# suggested: q = decodeURIComponent(window.location.search.substring(1)),
        s = /([^&;=]+)=?([^&;]*)/g //# original regex that does not allow for ; as a delimiter:   /([^&=]+)=?([^&]*)/g
    ;

    //# ma(make array) out of the v(alue)
    ma = function(v) {
        //# If the passed v(alue) hasn't been setup as an object
        if (typeof v != "object") {
            //# Grab the cv(current value) then setup the v(alue) as an object
            cv = v;
            v = {};
            v.length = 0;

            //# If there was a cv(current value), .push it into the new v(alue)'s array
            //#     NOTE: This may or may not be 100% logical to do... but it's better than loosing the original value
            if (cv) { Array.prototype.push.call(v, cv); }
        }
        return v;
    };

    //# While we still have key-value e(ntries) from the q(uerystring) via the s(earch regex)...
    while (e = s.exec(q)) { //# while((e = s.exec(q)) !== null) {
        //# Collect the open b(racket) location (if any) then set the d(ecoded) v(alue) from the above split key-value e(ntry) 
        b = e[1].indexOf("[");
        v = d(e[2]);

        //# As long as this is NOT a hash[]-style key-value e(ntry)
        if (b < 0) { //# b == "-1"
            //# d(ecode) the simple k(ey)
            k = d(e[1]);

            //# If the k(ey) already exists
            if (r[k]) {
                //# ma(make array) out of the k(ey) then .push the v(alue) into the k(ey)'s array in the r(eturn value)
                r[k] = ma(r[k]);
                Array.prototype.push.call(r[k], v);
            }
            //# Else this is a new k(ey), so just add the k(ey)/v(alue) into the r(eturn value)
            else {
                r[k] = v;
            }
        }
        //# Else we've got ourselves a hash[]-style key-value e(ntry) 
        else {
            //# Collect the d(ecoded) k(ey) and the d(ecoded) sk(sub-key) based on the b(racket) locations
            k = d(e[1].slice(0, b));
            sk = d(e[1].slice(b + 1, e[1].indexOf("]", b)));

            //# ma(make array) out of the k(ey) 
            r[k] = ma(r[k]);

            //# If we have a sk(sub-key), plug the v(alue) into it
            if (sk) { r[k][sk] = v; }
            //# Else .push the v(alue) into the k(ey)'s array
            else { Array.prototype.push.call(r[k], v); }
        }
    }

    //# Return the r(eturn value)
    return r;
};
Campbeln
la source
Pour obtenir les valeurs de chaîne de requête, vous pouvez utiliser cette fonction "GetParameterValues". En cela, il vous suffit de passer le nom du paramètre de requête et cela vous renverra la valeur $ (document) .ready (function () {var bid = GetParameterValues ​​('token');}); fonction GetParameterValues ​​(param) {var url = decodeURIComponent (window.location.href); url = url.slice (url.indexOf ('?') + 1) .split ('&'); pour (var i = 0; i <url.length; i ++) {var urlparam = url [i] .split ('='); if (urlparam [0] == param) {return urlparam [1]; }}
Mike Clark
1
J'utilise cela depuis un moment maintenant, et c'est génial jusqu'à présent. Sauf pour la gestion des tableaux encodés en url. L'utilisation l' q = decodeURIComponent(window.location.search.substring(1)),aide à le faire aussi.
Vladislav Dimitrov
31

C'est une fonction que j'ai créée il y a quelque temps et j'en suis très satisfait. Il n'est pas sensible à la casse - ce qui est pratique. De plus, si le QS demandé n'existe pas, il renvoie simplement une chaîne vide.

J'utilise une version compressée de cela. Je publie non compressé pour les types novices pour mieux expliquer ce qui se passe.

Je suis sûr que cela pourrait être optimisé ou fait différemment pour fonctionner plus rapidement, mais cela a toujours fonctionné très bien pour ce dont j'ai besoin.

Prendre plaisir.

function getQSP(sName, sURL) {
    var theItmToRtn = "";
    var theSrchStrg = location.search;
    if (sURL) theSrchStrg = sURL;
    var sOrig = theSrchStrg;
    theSrchStrg = theSrchStrg.toUpperCase();
    sName = sName.toUpperCase();
    theSrchStrg = theSrchStrg.replace("?", "&") theSrchStrg = theSrchStrg + "&";
    var theSrchToken = "&" + sName + "=";
    if (theSrchStrg.indexOf(theSrchToken) != -1) {
        var theSrchTokenLth = theSrchToken.length;
        var theSrchTokenLocStart = theSrchStrg.indexOf(theSrchToken) + theSrchTokenLth;
        var theLocOfNextAndSign = theSrchStrg.indexOf("&", theSrchTokenLocStart);
        theItmToRtn = unescape(sOrig.substring(theSrchTokenLocStart, theLocOfNextAndSign));
    }
    return unescape(theItmToRtn);
}
Clint
la source
Aussi, mieux vaut opter pour decodeURI () ou decodeURIComponent () au lieu de unescape (). developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Adarsh ​​Konchady
27

Nous venons de publier arg.js , un projet visant à résoudre ce problème une fois pour toutes. Cela a toujours été si difficile, mais maintenant vous pouvez faire:

var name = Arg.get("name");

ou obtenir le tout:

var params = Arg.all();

et si vous vous souciez de la différence entre ?query=trueet #hash=truealors vous pouvez utiliser les méthodes Arg.query()et Arg.hash().

Mat Ryer
la source
vous m'avez sauvé mec .. arg.js est la solution aucune des solutions n'obtient les valeurs de # dans IE 8 .. :( toute personne recherchant IE8 # obtient de la demande c'est la solution ..
Dilip Rajkumar
27

Le problème avec la première réponse à cette question est que ce ne sont pas les paramètres pris en charge placés après #, mais parfois il est également nécessaire d'obtenir cette valeur.

J'ai modifié la réponse pour lui permettre d'analyser une chaîne de requête complète avec un signe de hachage également:

var getQueryStringData = function(name) {
    var result = null;
    var regexS = "[\\?&#]" + name + "=([^&#]*)";
    var regex = new RegExp(regexS);
    var results = regex.exec('?' + window.location.href.split('?')[1]);
    if (results != null) {
        result = decodeURIComponent(results[1].replace(/\+/g, " "));
    }
    return result;
};
Ph0en1x
la source
1
C'est intéressant si vous en avez besoin, mais il n'y a pas de norme pour le format de la partie de hachage AFAIK, il n'est donc pas juste d'appeler cela comme une faiblesse de l'autre réponse.
Rup
2
Oui je sais. Mais dans mon application, j'intègre la navigation js tierce, qui a certains paramètres après le signe de hachage.
Ph0en1x
Par exemple, dans la page de recherche Google, la requête de recherche est suivie du signe de hachage «#».
etlds
25
function GetQueryStringParams(sParam)
{
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');

    for (var i = 0; i < sURLVariables.length; i++)
    {
        var sParameterName = sURLVariables[i].split('=');
        if (sParameterName[0] == sParam)
        {
            return sParameterName[1];
        }
    }
}​

Et voici comment vous pouvez utiliser cette fonction en supposant que l'URL est

http://dummy.com/?stringtext=jquery&stringword=jquerybyexample

var tech = GetQueryStringParams('stringtext');
var blog = GetQueryStringParams('stringword');
gewel
la source
Il y a déjà quelques implémentations de cette approche ici. Au minimum, vous devez décoderUriComponent () les valeurs de résultat. Cela pourrait également mal se comporter si vous ne spécifiez pas de valeur, par exemple ?stringtext&stringword=foo.
Rup
24

Si vous utilisez Browserify, vous pouvez utiliser le urlmodule de Node.js :

var url = require('url');

url.parse('http://example.com/?bob=123', true).query;

// returns { "bob": "123" }

Pour en savoir plus: URL Node.js v0.12.2 Manual & Documentation

EDIT: Vous pouvez utiliser l' interface URL , son assez largement adoptée dans presque tous les nouveaux navigateurs et si le code va s'exécuter sur un ancien navigateur, vous pouvez utiliser un polyfill comme celui-ci . Voici un exemple de code sur la façon d'utiliser l'interface URL pour obtenir des paramètres de requête (également appelés paramètres de recherche)

const url = new URL('http://example.com/?bob=123');
url.searchParams.get('bob'); 

Vous pouvez également utiliser URLSearchParams pour cela, voici un exemple de MDN pour le faire avec URLSearchParams:

var paramsString = "q=URLUtils.searchParams&topic=api";
var searchParams = new URLSearchParams(paramsString);

//Iterate the search parameters.
for (let p of searchParams) {
  console.log(p);
}

searchParams.has("topic") === true; // true
searchParams.get("topic") === "api"; // true
searchParams.getAll("topic"); // ["api"]
searchParams.get("foo") === null; // true
searchParams.append("topic", "webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=api&topic=webdev"
searchParams.set("topic", "More webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=More+webdev"
searchParams.delete("topic");
searchParams.toString(); // "q=URLUtils.searchParams"
nkh
la source
La documentation de l' urlAPI du module est ici: nodejs.org/api/url.html
andrezsanchez
C'est bien pour le développement de nw.js. Browserify n'est même pas nécessaire car la plupart des modules de nœuds fonctionnent comme dans une fenêtre nw.js. J'ai testé ce code et fonctionne comme un charme sans aucune modification.
Andrew Grothe
OHH c'est génial! URLSearchParams fonctionne parfaitement. Merci beaucoup!
Baran Emre
1
devrait probablement être le mieux voté, sans tracas avec des fonctions personnalisées et des bibliothèques supplémentaires. Il semble également être principalement adopté par les navigateurs 2019.
TheWhiteLlama