Maison >interface Web >js tutoriel >Pièges des URL et URLSearchParams en JavaScript
Travailler avec des URL en JavaScript et Node.js devrait être simple, mais un bug récent dans notre projet m'a conduit dans un terrier de bizarreries subtiles dans les API URL et URLSearchParams. Cet article explorera ces bizarreries, comment elles peuvent causer des problèmes dans votre code et ce que vous pouvez faire pour les éviter.
Nous avons rencontré ce problème lors de la génération d'URL et de l'ajout de signatures de hachage. Les paramètres de requête n'étaient pas systématiquement codés en pourcentage, ce qui entraînait un comportement inattendu et de mauvaises signatures de hachage.
Il est devenu clair que l'interaction entre les objets URL et URLSearchParams nécessitait une attention particulière.
La première surprise a été la différence entre URL.search et URLSearchParams.toString().
Soyez prudent lorsque vous utilisez .searchParams pour modifier l'URL car, selon la spécification WHATWG, l'objet URLSearchParams utilise des règles différentes pour déterminer les caractères à encoder en pourcentage. Par exemple, l'objet URL n'encodera pas en pourcentage le caractère ASCII tilde (~), tandis que URLSearchParams l'encodera toujours.
// Example 1 const url = new URL("https://example.com?param=foo bar"); console.log(url.search); // prints param=foo%20bar console.log(url.searchParams.toString()); // prints ?param=foo+bar // Example 2 const myURL = new URL('https://example.org/abc?foo=~bar'); console.log(myURL.search); // prints ?foo=~bar // Modify the URL via searchParams... myURL.searchParams.sort(); console.log(myURL.search); // prints ?foo=%7Ebar
Dans notre projet, nous devions réaffecter explicitement url.search = url.searchParams.toString() pour garantir que la chaîne de requête était codée de manière cohérente.
Un autre piège est la façon dont URLSearchParams gère les caractères. Par défaut, URLSearchParams interprète comme un espace, ce qui peut entraîner une corruption des données lors de l'encodage de données binaires ou de chaînes Base64.
const params = new URLSearchParams("bin=E+AXQB+A"); console.log(params.get("bin")); // "E AXQB A"
Une solution consiste à utiliser encodeURIComponent avant d'ajouter des valeurs à URLSearchParams :
params.append("bin", encodeURIComponent("E+AXQB+A"));
Plus de détails sont disponibles dans la documentation MDN.
Une autre subtilité apparaît lors de la comparaison des sorties de URLSearchParams.get et URLSearchParams.toString. Par exemple :
const params = new URLSearchParams("?key=value&key=other"); console.log(params.get("key")); // "value" (first occurrence) console.log(params.toString()); // "key=value&key=other" (all occurrences serialized)
Dans les scénarios à valeurs multiples, get renvoie uniquement la première valeur, tandis que toString sérialise toutes.
Dans notre projet, nous avons résolu le problème en réattribuant explicitement la propriété de recherche :
url.search = url.searchParams.toString(); url.searchParams.set( "hash", cryptography.createSha256HmacBase64UrlSafe(url.href, SECRET_KEY ?? "") );
Cela garantissait que tous les paramètres de requête étaient correctement codés avant d'ajouter la valeur de hachage.
L'interface WHATWG URLSearchParams et le module querystring ont un objectif similaire, mais l'objectif du module querystring est plus général, car il permet la personnalisation des caractères délimiteurs (& et =). D'un autre côté, l'API URLSearchParams est conçue uniquement pour les chaînes de requête d'URL.
querystring est plus performant que URLSearchParams mais n'est pas une API standardisée. Utilisez URLSearchParams lorsque les performances ne sont pas critiques ou lorsque la compatibilité avec le code du navigateur est souhaitable.
Lors de l'utilisation de URLSearchParams, contrairement au module de chaîne de requête, les clés en double sous forme de valeurs de tableau ne sont pas autorisées. Les tableaux sont stringifiés à l'aide de array.toString(), qui joint simplement tous les éléments du tableau avec des virgules.
// Example 1 const url = new URL("https://example.com?param=foo bar"); console.log(url.search); // prints param=foo%20bar console.log(url.searchParams.toString()); // prints ?param=foo+bar // Example 2 const myURL = new URL('https://example.org/abc?foo=~bar'); console.log(myURL.search); // prints ?foo=~bar // Modify the URL via searchParams... myURL.searchParams.sort(); console.log(myURL.search); // prints ?foo=%7Ebar
Avec le module querystring, la chaîne de requête 'foo=bar&abc=xyz&abc=123' est analysée en :
const params = new URLSearchParams("bin=E+AXQB+A"); console.log(params.get("bin")); // "E AXQB A"
Soyez prudent sur la façon dont URLSearchParams gère les caractères spéciaux (par exemple ~) et les espaces. Utilisez encodeURIComponent si nécessaire.
Comprenez la différence entre URL.search, URLSearchParams.get et URLSearchParams.toString pour éviter tout comportement inattendu.
Dans Node.js, utilisez querystring module si vous souhaitez analyser les clés de paramètres de requête en double sous forme de tableau.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!