Guide Complet de l'Analyse et de l'Encodage URL : De la Décomposition Structurelle au Traitement Sécurisé

Encodage

Structure Complète de l'URL

https://user:pass@example.com:8080/path/to/page?name=value&age=25#section
  │       │     │    │          │  │   │            │                │
  scheme  user  pass  host      port path           query            fragment
Composant Exemple Description
scheme https Protocole
userinfo user:pass Informations d'authentification (rarement utilisé)
host example.com Domaine ou IP
port 8080 Numéro de port (par défaut 80/443)
path /path/to/page Chemin
query ?name=value&age=25 Paramètres de query
fragment #section Ancre (non envoyée au serveur)

Analyse avec l'API URL

Analyse de base

const url = new URL('https://example.com:8080/path?q=test#section');

url.protocol  // "https:"
url.hostname  // "example.com"
url.port      // "8080"
url.pathname  // "/path"
url.search    // "?q=test"
url.hash      // "#section"
url.origin    // "https://example.com:8080"
url.href      // URL complète

Analyse des paramètres de query

const url = new URL('https://example.com/api?name=Alice&age=25&tags=js&tags=css');

// URLSearchParams
url.searchParams.get('name')     // "Alice"
url.searchParams.get('age')      // "25"
url.searchParams.getAll('tags')  // ["js", "css"]
url.searchParams.has('name')     // true
url.searchParams.delete('age')

// Itérer
for (const [key, value] of url.searchParams) {
  console.log(`${key} = ${value}`);
}

Modifier l'URL

const url = new URL('https://example.com/page');

url.pathname = '/new-page';
url.searchParams.set('sort', 'desc');
url.searchParams.append('filter', 'active');
url.hash = '#top';

console.log(url.toString());
// "https://example.com/new-page?sort=desc&filter=active#top"

Règles d'Encodage URL

Pourquoi l'encodage est-il nécessaire ?

Les URL ne permettent que les caractères ASCII, les autres caractères doivent être encodés :

Original : https://example.com/search?q=你好 世界
Encodé : https://example.com/search?q=%E4%BD%A0%E5%A5%BD%20%E4%B8%96%E7%95%8C

encodeURI vs encodeURIComponent

Fonction Portée de l'encodage Utilisation
encodeURI Conserve les caractères structurels de l'URL (:/?#[]@!$&'()*+,;=) Encoder une URL complète
encodeURIComponent Encode tous les caractères non-ASCII + caractères réservés Encoder les valeurs de paramètres de query
const url = 'https://example.com/path?name=你好&redirect=/home';

// encodeURI : conserve la structure de l'URL
encodeURI(url);
// "https://example.com/path?name=%E4%BD%A0%E5%A5%BD&redirect=/home"

// encodeURIComponent : encode tous les caractères spéciaux
encodeURIComponent(url);
// "https%3A%2F%2Fexample.com%2Fpath%3Fname%3D%E4%BD%A0%E5%A5%BD%26redirect%3D%2Fhome"

// ✅ Utilisation correcte : valeurs de paramètres avec encodeURIComponent
const name = '你好 世界';
const redirect = '/home';
const fullUrl = `https://example.com/path?name=${encodeURIComponent(name)}&redirect=${encodeURIComponent(redirect)}`;

Tableau d'encodage courant

Caractère Encodage Description
Espace %20 Ne pas utiliser + dans les URL
+ %2B Dans les paramètres de query, + est décodé comme un espace
& %26 Séparateur de paramètres de query
= %3D Séparateur clé-valeur
# %23 Identifiant d'ancre
% %25 Le préfixe d'encodage lui-même
Chinois %E4%BD%A0 Encodage UTF-8 sur trois octets

Utiliser ToolsKu pour Encoder/Décoder les URL

  1. Ouvrez l'outil d'encodage/décodage URL
  2. Collez l'URL ou le texte dans le champ de saisie
  3. Cliquez sur « Encoder » ou « Décoder »
  4. Consultez le résultat

Traitement Sécurisé des URL

1. Prévenir les injections URL

// ❌ Dangereux : concaténer directement l'entrée utilisateur
const url = `/api/users/${userId}`;

// ✅ Sécurisé : valider + encoder
function buildUserUrl(userId) {
  if (!/^\d+$/.test(userId)) {
    throw new Error('Invalid user ID');
  }
  return `/api/users/${encodeURIComponent(userId)}`;
}

2. Prévenir les redirections ouvertes

// ❌ Dangereux : l'utilisateur peut spécifier n'importe quelle URL de redirection
app.get('/login', (req, res) => {
  res.redirect(req.query.redirect);
});

// ✅ Sécurisé : validation par liste blanche
function safeRedirect(url, allowedHosts) {
  try {
    const parsed = new URL(url, 'https://example.com');
    if (allowedHosts.includes(parsed.hostname)) {
      return url;
    }
  } catch {
    // URL invalide
  }
  return '/'; // Rediriger vers la page d'accueil
}

3. Prévenir le XSS via URL

// ❌ Dangereux : protocole javascript:
const url = 'javascript:alert(document.cookie)';

// ✅ Sécurisé : autoriser uniquement les protocoles http/https
function sanitizeUrl(url) {
  try {
    const parsed = new URL(url);
    if (['http:', 'https:'].includes(parsed.protocol)) {
      return url;
    }
  } catch {
    // URL invalide
  }
  return 'about:blank';
}

API URLPattern (Nouveau Standard)

// Correspondance de routes
const pattern = new URLPattern({ pathname: '/api/users/:id' });

const result = pattern.exec('https://example.com/api/users/123');
if (result) {
  console.log(result.pathname.groups.id); // "123"
}

// Modèle plus complexe
const apiPattern = new URLPattern({
  protocol: 'https',
  hostname: ':env.example.com',
  pathname: '/api/:version/:resource/:id?',
});

const match = apiPattern.exec('https://prod.example.com/api/v2/users/456');
match.hostname.groups.env      // "prod"
match.pathname.groups.version  // "v2"
match.pathname.groups.resource // "users"
match.pathname.groups.id       // "456"

Meilleures Pratiques pour Construire les Paramètres de Query

Utiliser URLSearchParams

// ✅ Recommandé : utiliser URLSearchParams
const params = new URLSearchParams({
  q: '搜索关键词',
  sort: 'desc',
  page: '1',
  limit: '20',
});

params.append('tags', 'javascript');
params.append('tags', 'css');

const url = `https://api.example.com/search?${params}`;
// "https://api.example.com/search?q=...&sort=desc&page=1&limit=20&tags=javascript&tags=css"

Conventions courantes pour les paramètres de type tableau

Convention Exemple Framework serveur
Clés répétées ?tags=js&tags=css Express, Koa
Suffixe entre crochets ?tags[]=js&tags[]=css PHP, Rails
Indice ?tags[0]=js&tags[1]=css PHP
Séparés par des virgules ?tags=js,css Personnalisé

Questions Fréquentes

Pourquoi l'espace dans les URL est-il parfois %20 et parfois + ?

  • Dans le chemin URL : espace = %20 (standard)
  • Dans les paramètres de query : espace = + ou %20 (+ est la convention application/x-www-form-urlencoded)
  • Recommandation : utiliser %20 uniformément, éviter l'ambiguïté

Les URL ont-elles une longueur maximale ?

Scénario Limite
Barre d'URL de Chrome 2Mo
Barre d'URL de Firefox Sans limite
Barre d'URL de IE 2083 caractères
Requête HTTP GET Le serveur décide (généralement 8Ko)
Limite de sécurité 2048 caractères (compatible avec tous les navigateurs)

Les paramètres dépassant 2048 caractères doivent utiliser des requêtes POST.


Résumé

L'URL est la pierre angulaire du Web ; comprendre sa structure, ses règles d'encodage et son traitement sécurisé est une compétence fondamentale pour chaque développeur. Points clés : encoder les valeurs de paramètres avec encodeURIComponent, vérifier les protocoles pour prévenir le XSS, valider par liste blanche pour prévenir les redirections ouvertes. L'outil d'encodage/décodage URL de ToolsKu vous aide à traiter rapidement les problèmes d'encodage URL.

#URL解析#URL编码#查询参数#Web开发#教程