Catégories
Astuces et Design

Obtenir les paramètres d'URL avec JavaScript – SitePoint

Les paramètres d'URL (également appelés paramètres de chaîne de requête ou variables d'URL) sont utilisés pour envoyer de petites quantités de données de page en page, ou de client à serveur via une URL. Ils peuvent contenir toutes sortes d'informations utiles, telles que des requêtes de recherche, des références de liens, des informations sur les produits, les préférences des utilisateurs, etc.

Dans cet article, nous allons vous montrer comment analyser et manipuler les paramètres d'URL à l'aide de JavaScript.

Cet article a été mis à jour en 2020 pour plus de pertinence et d'exactitude. Pour une connaissance plus approfondie de JavaScript, lisez notre livre, JavaScript: Novice to Ninja, 2nd Edition.

Obtention d'un paramètre d'URL

Dans les navigateurs modernes, cela est devenu beaucoup plus facile, grâce à l'interface URLSearchParams. Cela définit une multitude de méthodes utilitaires pour travailler avec la chaîne de requête d'une URL.

En supposant que notre URL est https://example.com/?product=shirt&color=blue&newuser&size=m, nous pouvons saisir la chaîne de requête en utilisant window.location.search:

const queryString = window.location.search;
console.log(queryString);
// ?product=shirt&color=blue&newuser&size=m

Nous pouvons ensuite analyser les paramètres de la chaîne de requête en utilisant URLSearchParams:

const urlParams = new URLSearchParams(queryString);

Ensuite, nous appelons l'une de ses méthodes sur le résultat.

Par exemple, URLSearchParams.get() renverra la première valeur associée au paramètre de recherche donné:

const product = urlParams.get('product')
console.log(product);
// shirt

const color = urlParams.get('color')
console.log(color);
// blue

const newUser = urlParams.get('newuser')
console.log(newUser);
// empty string

Autres méthodes utiles

Vérification de la présence d'un paramètre

Vous pouvez utiliser URLSearchParams.has() pour vérifier si un certain paramètre existe:

console.log(urlParams.has('product'));
// true

console.log(urlParams.has('paymentmethod'));
// false

Obtention de toutes les valeurs d'un paramètre

Vous pouvez utiliser URLSearchParams.getAll() pour renvoyer toutes les valeurs associées à un paramètre particulier:

console.log(urlParams.getAll('size'));
// ( 'm' )

//Programmatically add a second size parameter.
urlParams.append('size', 'xl');

console.log(urlParams.getAll('size'));
// ( 'm', 'xl' )

Itération sur les paramètres

URLSearchParams fournit également quelques familiers Object méthodes d'itérateur, vous permettant d'itérer sur ses clés, valeurs et entrées:

const
  keys = urlParams.keys(),
  values = urlParams.values(),
  entries = urlParams.entries();

for (const key of keys) console.log(key);
// product, color, newuser, size

for (const value of values) console.log(value);
// shirt, blue, , m

for(const entry of entries) {
  console.log(`${entry(0)}: ${entry(1)}`);
}
// product: shirt
// color: blue
// newuser:
// size: m

Prise en charge du navigateur

Prise en charge du navigateur pour URLSearchParams est bon. Au moment de la rédaction, il était pris en charge dans tous les principaux navigateurs.

Données sur la prise en charge de la fonction urlsearchparams sur les principaux navigateurs de caniuse.com

Un polyfill est disponible si vous devez prendre en charge les navigateurs hérités tels qu'Internet Explorer. Ou, vous pouvez suivre le reste de ce didacticiel et apprendre à rouler le vôtre.

Rolling Your Own Query String Parsing Function

Restons avec l'URL que nous utilisions dans la section précédente:

http://example.com/?product=shirt&color=blue&newuser&size=m

Voici une fonction pour vous donner tous les paramètres d'URL en tant qu'objet soigné:

function getAllUrlParams(url) {

  // get query string from url (optional) or window
  var queryString = url ? url.split('?')(1) : window.location.search.slice(1);

  // we'll store the parameters here
  var obj = {};

  // if query string exists
  if (queryString) {

    // stuff after # is not part of query string, so get rid of it
    queryString = queryString.split('#')(0);

    // split our query string into its component parts
    var arr = queryString.split('&');

    for (var i = 0; i < arr.length; i++) {
      // separate the keys and the values
      var a = arr(i).split('=');

      // set parameter name and value (use 'true' if empty)
      var paramName = a(0);
      var paramValue = typeof (a(1)) === 'undefined' ? true : a(1);

      // (optional) keep case consistent
      paramName = paramName.toLowerCase();
      if (typeof paramValue === 'string') paramValue = paramValue.toLowerCase();

      // if the paramName ends with square brackets, e.g. colors() or colors(2)
      if (paramName.match(/((d+)?)$/)) {

        // create key if it doesn't exist
        var key = paramName.replace(/((d+)?)/, '');
        if (!obj(key)) obj(key) = ();

        // if it's an indexed array e.g. colors(2)
        if (paramName.match(/(d+)$/)) {
          // get the index value and add the entry at the appropriate position
          var index = /((d+))/.exec(paramName)(1);
          obj(key)(index) = paramValue;
        } else {
          // otherwise add the value to the end of the array
          obj(key).push(paramValue);
        }
      } else {
        // we're dealing with a string
        if (!obj(paramName)) {
          // if it doesn't exist, create property
          obj(paramName) = paramValue;
        } else if (obj(paramName) && typeof obj(paramName) === 'string'){
          // if property does exist and it's a string, convert it to an array
          obj(paramName) = (obj(paramName));
          obj(paramName).push(paramValue);
        } else {
          // otherwise add the property
          obj(paramName).push(paramValue);
        }
      }
    }
  }

  return obj;
}

Vous verrez bientôt comment cela fonctionne, mais d'abord, voici quelques exemples d'utilisation:

getAllUrlParams().product; // 'shirt'
getAllUrlParams().color; // 'blue'
getAllUrlParams().newuser; // true
getAllUrlParams().nonexistent; // undefined
getAllUrlParams('http://test.com/?a=abc').a; // 'abc'

Et voici une démo avec laquelle vous pourrez jouer.

Voir le Pen rQGWpP de SitePoint (@SitePoint) sur CodePen.

Choses à savoir avant d'utiliser cette fonction

  • Notre fonction suppose que les paramètres sont séparés par le & comme indiqué dans les spécifications du W3C. Cependant, le format des paramètres d'URL en général n'est pas clairement défini, vous pouvez donc parfois voir ; ou & comme séparateurs.

  • Notre fonction fonctionne toujours si un paramètre n'a pas de signe égal ou s'il a un signe égal mais pas de valeur.

  • Les valeurs des paramètres en double sont mises dans un tableau.

Si vous vouliez juste une fonction que vous pourriez insérer dans votre code, vous avez terminé maintenant. Si vous souhaitez comprendre le fonctionnement de la fonction, lisez la suite.

La section suivante suppose que vous connaissez certains JavaScript, y compris les fonctions, les objets et les tableaux. Si vous avez besoin d'un rafraîchissement, consultez la référence JavaScript MDN.

Fonctionnement de la fonction

Dans l'ensemble, la fonction prend la chaîne de requête d'une URL (la partie après le ? et avant le #) et crache les données dans un objet soigné.

Tout d'abord, cette ligne indique que si nous avons spécifié une URL, récupérez tout après le point d'interrogation, mais sinon, utilisez simplement l'URL de la fenêtre:

var queryString = url ? url.split('?')(1) : window.location.search.slice(1);

Ensuite, nous allons créer un objet pour stocker nos paramètres:

var obj = {};

Si la chaîne de requête existe, nous allons commencer à l'analyser. Nous devons d'abord nous assurer de raser la partie à partir du #, car il ne fait pas partie de la chaîne de requête:

queryString = queryString.split('#')(0);

Nous pouvons maintenant diviser la chaîne de requête en ses composants:

var arr = queryString.split('&');

Cela nous donnera un tableau qui ressemble à ceci:

('product=shirt', 'color=blue', 'newuser', 'size=m')

Ensuite, nous allons parcourir ce tableau et diviser chaque élément en une clé et une valeur, que nous mettrons bientôt dans notre objet:

var a = arr(i).split('=');

Attribuons la clé et une valeur à des variables individuelles. S'il n'y a pas de valeur de paramètre, nous la réglerons sur true pour indiquer que le nom du paramètre existe. N'hésitez pas à modifier cela en fonction de votre cas d'utilisation:

var paramName = a(0);
var paramValue = typeof (a(1)) === 'undefined' ? true : a(1);

Facultativement, vous pouvez définir tous les noms et valeurs de paramètres en minuscules. De cette façon, vous pouvez éviter les situations où quelqu'un envoie du trafic vers une URL avec example=TRUE au lieu de example=true et votre script se casse. (J'ai vu cela se produire.) Cependant, si votre chaîne de requête doit être sensible à la casse, n'hésitez pas à omettre cette partie:

paramName = paramName.toLowerCase();
if (typeof paramValue === 'string') paramValue = paramValue.toLowerCase();

Ensuite, nous devons traiter les différents types de données que nous pouvons recevoir dans paramName. Il peut s'agir d'un tableau indexé, d'un tableau non indexé ou d'une chaîne régulière.

S'il s'agit d'un tableau indexé, nous voulons que le tableau correspondant paramValue être un tableau, avec la valeur insérée à la position correcte. S'il s'agit d'un tableau non indexé, nous voulons que le tableau correspondant paramValue être un tableau avec l'élément poussé dessus. S'il s'agit d'une chaîne, nous voulons créer une propriété régulière sur l'objet et affecter la paramValue à elle, sauf si la propriété existe déjà, auquel cas nous voulons convertir l'existant paramValue à un tableau et pousser l'entrée paramValue à cela.

Pour illustrer cela, voici quelques exemples d'entrée, avec la sortie que nous attendons:

getAllUrlParams('http://example.com/?colors(0)=red&colors(2)=green&colors(6)=blue');
// { "colors": ( "red", null, "green", null, null, null, "blue" ) }

getAllUrlParams('http://example.com/?colors()=red&colors()=green&colors()=blue');
// { "colors": ( "red", "green", "blue" ) }

getAllUrlParams('http://example.com/?colors=red&colors=green&colors=blue');
// { "colors": ( "red", "green", "blue" ) }

getAllUrlParams('http://example.com/?product=shirt&color=blue&newuser&size=m');
// { "product": "shirt", "color": "blue", "newuser": true, "size": "m" }

Et voici le code pour implémenter la fonctionnalité:

if (paramName.match(/((d+)?)$/)) {
  var key = paramName.replace(/((d+)?)/, '');
  if (!obj(key)) obj(key) = ();

  if (paramName.match(/(d+)$/)) {
    var index = /((d+))/.exec(paramName)(1);
    obj(key)(index) = paramValue;
  } else {
    obj(key).push(paramValue);
  }
} else {
  if (!obj(paramName)) {
    obj(paramName) = paramValue;
  } else if (obj(paramName) && typeof obj(paramName) === 'string'){
    obj(paramName) = (obj(paramName));
    obj(paramName).push(paramValue);
  } else {
    obj(paramName).push(paramValue);
  }
}

Enfin, nous renvoyons notre objet avec les paramètres et les valeurs.

Si votre URL contient des caractères spéciaux codés comme des espaces (codés comme %20), vous pouvez également les décoder pour obtenir la valeur d'origine comme ceci:

// assume a url parameter of test=a%20space

var original = getAllUrlParams().test; // 'a%20space'
var decoded = decodeURIComponent(original); // 'a space'

Faites juste attention à ne pas décoder quelque chose qui est déjà décodé, sinon votre script se trompera, surtout si des pourcentages sont impliqués.

Quoi qu'il en soit, félicitations! Vous savez maintenant comment obtenir un paramètre d'URL et, espérons-le, vous avez trouvé d'autres astuces en cours de route.

Conclusion

Le code de cet article fonctionne pour les cas d'utilisation les plus courants où vous obtiendrez un paramètre de requête URL. Si vous travaillez avec des cas de bord, tels que des séparateurs rares ou un formatage spécial, assurez-vous de tester et de régler en conséquence.

Si vous souhaitez en faire plus avec les URL, des bibliothèques spécifiques sont disponibles, telles que la chaîne de requête et Medialize URI.js. Mais comme il s'agit essentiellement de manipulation de chaînes, il est souvent logique d'utiliser simplement du JavaScript. Que vous utilisiez votre propre code ou que vous alliez avec une bibliothèque, assurez-vous de tout vérifier et assurez-vous que cela fonctionne pour vos cas d'utilisation.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *