DevToolBoxGRATUIT
Blog

Encodage & Décodage URL : Guide Complet du Percent-Encoding

10 min de lecturepar DevToolBox

L'encodage URL (egalement connu sous le nom d'encodage pourcent) est l'un des mecanismes les plus essentiels du developpement web. Chaque fois que vous soumettez un formulaire, cliquez sur un lien avec des parametres de requete ou appelez une API REST, des operations d'encodage et de decodage URL se produisent. Ce guide complet couvre tout, de la specification RFC 3986 aux exemples de code pratiques en JavaScript, Python, Bash, PHP et Java.

Essayez notre outil gratuit d'encodage/decodage URL en ligne.

Qu'est-ce que l'encodage URL (encodage pourcent) ?

L'encodage URL, defini dans la RFC 3986, remplace les caracteres non securises par un signe pourcent (%) suivi de deux chiffres hexadecimaux. Par exemple, un espace devient %20.

Les URLs ne peuvent contenir qu'un ensemble limite de caracteres ASCII. Les caracteres surs qui n'ont pas besoin d'encodage sont : lettres, chiffres et quatre caracteres speciaux : -, _, ., ~. Tous les autres caracteres doivent etre encodes.

Les caracteres comme &, =, ? et # ont des significations structurelles dans les URLs. Sans encodage URL, les URLs seraient cassees ou mal interpretees.

Comment fonctionne l'encodage URL

Le processus d'encodage URL suit un algorithme simple :

  1. Convertir le caractere en octets UTF-8.
  2. Pour chaque octet, ecrire % suivi de la valeur hexadecimale.
  3. Les caracteres non reserves restent inchanges.
  4. Les caracteres reserves ne sont encodes que dans les contextes ou ils seraient mal interpretes.

Exemple : Hello World! devient Hello%20World%21.

Exemple multi-octets UTF-8 : Les caracteres non-ASCII produisent plusieurs octets percent-encodes.

Table de reference d'encodage URL

Table de reference des caracteres couramment encodes :

CharacterEncodedDescription
(space)%20Space
!%21Exclamation mark
#%23Hash / Fragment
$%24Dollar sign
%%25Percent sign
&%26Ampersand
'%27Apostrophe
(%28Left parenthesis
)%29Right parenthesis
*%2AAsterisk
+%2BPlus sign
,%2CComma
/%2FForward slash
:%3AColon
;%3BSemicolon
=%3DEquals sign
?%3FQuestion mark
@%40At sign
[%5BLeft bracket
]%5DRight bracket
{%7BLeft brace
}%7DRight brace
|%7CPipe
<%3CLess than
>%3EGreater than
"%22Double quote

Encodage des espaces : %20 vs +

Il existe deux facons d'encoder les espaces dans les URLs :

%20 : Encodage standard RFC 3986 pour les URIs.

+ : Utilise par application/x-www-form-urlencoded (formulaires HTML).

Lequel utiliser ? Utilisez %20 pour construire des URLs programmatiquement. Le + est utilise automatiquement pour les formulaires.

// Space encoding comparison

// RFC 3986 (URI standard) — space = %20
"hello world"  →  "hello%20world"
// Used in: URL paths, API endpoints, general URIs

// application/x-www-form-urlencoded — space = +
"hello world"  →  "hello+world"
// Used in: HTML form submissions, URLSearchParams

// JavaScript comparison:
encodeURIComponent("hello world")  // "hello%20world"  (%20)
new URLSearchParams({q: "hello world"}).toString()  // "q=hello+world"  (+)

// Python comparison:
urllib.parse.quote("hello world")      # "hello%20world"  (%20)
urllib.parse.urlencode({"q": "hello world"})  # "q=hello+world"  (+)

// PHP comparison:
rawurlencode("hello world")  // "hello%20world"  (%20)
urlencode("hello world")     // "hello+world"    (+)

Exemples de code d'encodage/decodage URL

JavaScript encodage/decodage URL

JavaScript offre encodeURIComponent et encodeURI. Comprendre quand utiliser chacun est essentiel :

// ===== encodeURIComponent vs encodeURI =====

// encodeURIComponent — encodes EVERYTHING except: A-Z a-z 0-9 - _ . ~
// Use for: individual query parameter values, path segments
encodeURIComponent("hello world & goodbye");
// "hello%20world%20%26%20goodbye"

encodeURIComponent("price=100&category=books");
// "price%3D100%26category%3Dbooks"

// encodeURI — preserves URL structure characters: : / ? # & = @ + $
// Use for: encoding a complete URL
encodeURI("https://example.com/search?q=hello world&lang=en");
// "https://example.com/search?q=hello%20world&lang=en"

// WARNING: Do NOT use encodeURIComponent on full URLs!
encodeURIComponent("https://example.com/path");
// "https%3A%2F%2Fexample.com%2Fpath"  ← BROKEN URL!

// ===== Decoding =====
decodeURIComponent("hello%20world%20%26%20goodbye");
// "hello world & goodbye"

decodeURI("https://example.com/search?q=hello%20world");
// "https://example.com/search?q=hello world"

// ===== URLSearchParams (handles form encoding automatically) =====
const params = new URLSearchParams({
  query: "cats & dogs",
  page: "1",
  filter: "price > 50"
});
params.toString();
// "query=cats+%26+dogs&page=1&filter=price+%3E+50"
// Note: spaces become + (form encoding), & in values becomes %26

// Parse query string
const parsed = new URLSearchParams("?q=hello+world&lang=en");
parsed.get("q");  // "hello world" (+ decoded to space)
parsed.get("lang");  // "en"

// ===== Building URLs with the URL API =====
const url = new URL("https://api.example.com/search");
url.searchParams.set("q", "hello world & more");
url.searchParams.set("limit", "10");
url.toString();
// "https://api.example.com/search?q=hello+world+%26+more&limit=10"

Python encodage/decodage URL

Le module urllib.parse de Python fournit des fonctions completes d'encodage URL :

import urllib.parse

# ===== quote / unquote (RFC 3986 percent-encoding) =====

# Encode a string (spaces become %20)
urllib.parse.quote("hello world & goodbye")
# "hello%20world%20%26%20goodbye"

# By default, / is NOT encoded (safe="/")
urllib.parse.quote("/path/to/file name.txt")
# "/path/to/file%20name.txt"

# Encode everything including /
urllib.parse.quote("/path/to/file", safe="")
# "%2Fpath%2Fto%2Ffile"

# Decode
urllib.parse.unquote("hello%20world%20%26%20goodbye")
# "hello world & goodbye"

# ===== urlencode (for query strings, uses + for spaces) =====
params = {"q": "cats & dogs", "page": 1, "filter": "price > 50"}
urllib.parse.urlencode(params)
# "q=cats+%26+dogs&page=1&filter=price+%3E+50"

# ===== quote_plus (form encoding, spaces become +) =====
urllib.parse.quote_plus("hello world")
# "hello+world"

urllib.parse.unquote_plus("hello+world")
# "hello world"

# ===== With the requests library =====
import requests

# requests handles URL encoding automatically
response = requests.get(
    "https://api.example.com/search",
    params={"q": "hello world", "lang": "en"}
)
# Actual URL: https://api.example.com/search?q=hello+world&lang=en

# For path segments, encode manually
username = "john@example.com"
url = f"https://api.example.com/users/{urllib.parse.quote(username, safe='')}"
# "https://api.example.com/users/john%40example.com"

Bash / curl encodage URL

Avec curl, le flag --data-urlencode est l'approche la plus simple :

# ===== curl --data-urlencode =====

# GET request with URL-encoded query parameter
curl -G "https://api.example.com/search" \
  --data-urlencode "q=hello world & more" \
  --data-urlencode "lang=en"
# Request URL: /search?q=hello%20world%20%26%20more&lang=en

# POST with form-encoded body
curl -X POST "https://api.example.com/submit" \
  --data-urlencode "name=John Doe" \
  --data-urlencode "message=Hello! How are you?"

# ===== Pure Bash URL encoding (using printf) =====
urlencode() {
  local string="${1}"
  local strlen=${#string}
  local encoded=""
  local pos c o
  for (( pos=0 ; pos<strlen ; pos++ )); do
    c=${string:$pos:1}
    case "$c" in
      [-_.~a-zA-Z0-9]) o="${c}" ;;
      *) printf -v o '%%%02X' "'$c" ;;
    esac
    encoded+="${o}"
  done
  echo "${encoded}"
}

urlencode "hello world & goodbye"
# "hello%20world%20%26%20goodbye"

# ===== Using Python one-liner in Bash =====
python3 -c "import urllib.parse; print(urllib.parse.quote('hello world'))"
# "hello%20world"

# ===== Decode URL-encoded strings =====
python3 -c "import urllib.parse; print(urllib.parse.unquote('hello%20world'))"
# "hello world"

PHP encodage/decodage URL

PHP fournit urlencode() et rawurlencode() :

<?php
// ===== urlencode / urldecode =====
// Uses + for spaces (application/x-www-form-urlencoded)

echo urlencode("hello world & goodbye");
// "hello+world+%26+goodbye"

echo urldecode("hello+world+%26+goodbye");
// "hello world & goodbye"

// ===== rawurlencode / rawurldecode =====
// Uses %20 for spaces (RFC 3986)

echo rawurlencode("hello world & goodbye");
// "hello%20world%20%26%20goodbye"

echo rawurldecode("hello%20world%20%26%20goodbye");
// "hello world & goodbye"

// ===== When to use which? =====
// urlencode()    → for query string values (form-style)
// rawurlencode() → for URL path segments (RFC 3986)

// Building a URL with encoded path and query
$path = rawurlencode("my file.pdf");
$query = urlencode("search term & more");
$url = "https://example.com/files/{$path}?q={$query}";
// "https://example.com/files/my%20file.pdf?q=search+term+%26+more"

// ===== http_build_query (encode arrays as query strings) =====
$params = [
    "q" => "cats & dogs",
    "page" => 1,
    "tags" => ["php", "url encoding"]
];
echo http_build_query($params);
// "q=cats+%26+dogs&page=1&tags%5B0%5D=php&tags%5B1%5D=url+encoding"
?>

Java encodage/decodage URL

Les classes URLEncoder et URLDecoder de Java gerent l'encodage URL :

import java.net.URLEncoder;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

// ===== URLEncoder.encode (uses + for spaces) =====

// Always specify UTF-8 charset!
String encoded = URLEncoder.encode(
    "hello world & goodbye", StandardCharsets.UTF_8
);
// "hello+world+%26+goodbye"

// Decode
String decoded = URLDecoder.decode(
    "hello+world+%26+goodbye", StandardCharsets.UTF_8
);
// "hello world & goodbye"

// ===== Convert + to %20 for RFC 3986 compliance =====
String rfc3986 = URLEncoder.encode("hello world", StandardCharsets.UTF_8)
    .replace("+", "%20");
// "hello%20world"

// ===== Java 11+ URI encoding =====
import java.net.URI;

URI uri = URI.create("https://example.com/search");
// For building URLs with encoded parameters:
String query = "q=" + URLEncoder.encode("hello world", StandardCharsets.UTF_8);
URI fullUri = URI.create("https://example.com/search?" + query);
// https://example.com/search?q=hello+world

// ===== Encoding path segments =====
String pathSegment = URLEncoder.encode("my file.pdf", StandardCharsets.UTF_8)
    .replace("+", "%20");
String url = "https://example.com/files/" + pathSegment;
// "https://example.com/files/my%20file.pdf"

Erreurs courantes d'encodage URL

Les pieges les plus courants a eviter :

Double encodage : Encoder une chaine deja encodee. %20 devient %2520.

// Double encoding example — a common bug!

const value = "hello world";

// Correct: encode once
const correct = encodeURIComponent(value);
// "hello%20world" ✓

// Bug: encode twice
const doubleEncoded = encodeURIComponent(encodeURIComponent(value));
// "hello%2520world" ✗  (%25 is the encoded form of %)

// How to detect double encoding:
// If you see %25 in your URLs, you likely have a double encoding issue
// %2520 = double-encoded space (%25 = %, 20 = space)
// %253A = double-encoded colon (%25 = %, 3A = :)

Encoder l'URL entiere : Utiliser encodeURIComponent() sur une URL complete casse la structure.

// Encoding the entire URL — WRONG!
const url = "https://example.com/path?q=hello world";

// WRONG: breaks URL structure
encodeURIComponent(url);
// "https%3A%2F%2Fexample.com%2Fpath%3Fq%3Dhello%20world"

// CORRECT option 1: use encodeURI for full URLs
encodeURI(url);
// "https://example.com/path?q=hello%20world"

// CORRECT option 2: encode only the value
const base = "https://example.com/path";
const query = encodeURIComponent("hello world");
const fullUrl = base + "?q=" + query;
// "https://example.com/path?q=hello%20world"

Oublier UTF-8 : Toujours utiliser UTF-8 pour l'encodage URL.

Ne pas encoder les segments de chemin : Les chemins avec espaces doivent aussi etre encodes.

Mauvaise gestion du signe + : + signifie espace dans les formulaires, mais c'est un literal dans les URLs.

Encodage URL dans les APIs

Comprendre l'encodage URL est crucial pour les APIs :

Parametres de requete : Chaque nom et valeur de parametre doit etre encode individuellement.

Parametres de chemin : Les valeurs dans les chemins d'URL doivent aussi etre encodees.

Donnees de formulaire : application/x-www-form-urlencoded utilise + pour les espaces.

Charges JSON : Le contenu JSON dans le corps d'une requete n'a pas besoin d'encodage URL.

// API URL encoding examples

// Query parameters — encode each value individually
const searchTerm = 'price > 100 & category = "electronics"';
const apiUrl = `https://api.example.com/search?q=${encodeURIComponent(searchTerm)}&limit=10`;
// "https://api.example.com/search?q=price%20%3E%20100%20%26%20...&limit=10"

// Path parameters — encode values embedded in paths
const username = "john@example.com";
const profileUrl = `https://api.example.com/users/${encodeURIComponent(username)}/profile`;
// "https://api.example.com/users/john%40example.com/profile"

// Form data (POST) — uses + for spaces
const formBody = new URLSearchParams({
  username: "john doe",
  password: "p@ss w0rd!"
}).toString();
// "username=john+doe&password=p%40ss+w0rd%21"

// JSON as query parameter — encode the entire JSON string
const filters = JSON.stringify({ price: { min: 10, max: 100 } });
const url = `/api/products?filters=${encodeURIComponent(filters)}`;
// "/api/products?filters=%7B%22price%22%3A%7B%22min%22%3A10%2C%22max%22%3A100%7D%7D"

Questions frequemment posees

Qu'est-ce que l'encodage URL et pourquoi est-il necessaire ?

L'encodage URL remplace les caracteres non securises par des sequences pourcent-hexadecimales pour une transmission sure dans les URLs. Les caracteres speciaux comme &, =, ? et # ont des significations structurelles et doivent etre encodes comme donnees.

Quelle est la difference entre encodeURI et encodeURIComponent ?

encodeURI() preserve les caracteres structurels de l'URL (:, /, ?, #). encodeURIComponent() encode tout sauf les caracteres non reserves. Utilisez encodeURIComponent pour les valeurs de parametres individuels.

Faut-il utiliser %20 ou + pour les espaces ?

Utilisez %20 pour les URLs (RFC 3986). Utilisez + uniquement pour application/x-www-form-urlencoded. En cas de doute, %20 est le choix le plus sur.

L'encodage URL est une competence fondamentale du developpement web. Utilisez notre outil gratuit pour un encodage et decodage instantanes.

Encodez et decodez des URLs instantanement avec notre outil gratuit.

𝕏 Twitterin LinkedIn
Cet article vous a-t-il aidé ?

Restez informé

Recevez des astuces dev et les nouveaux outils chaque semaine.

Pas de spam. Désabonnez-vous à tout moment.

Essayez ces outils associés

%20URL Encoder/Decoder🔗URL Parser%←URL Decoder%%Percent Encoding Tool

Articles connexes

Encodage URL des caractères spéciaux : Table de référence complète

Référence complète du percent-encoding URL. Table de recherche, encodeURIComponent vs encodeURI, erreurs courantes.

Encodage & Décodage Base64 : Guide Complet avec Exemples de Code

Encodeur et décodeur Base64 gratuit en ligne. Apprenez le fonctionnement du Base64 avec des exemples en JavaScript, Python, Bash et PowerShell.

Guide URL Encoder Decoder en Ligne : Encodage Pourcent, RFC 3986 et Bonnes Pratiques

Guide complet de l'encodage URL (encodage pourcent). RFC 3986, encodeURIComponent vs encodeURI, Python urllib.parse, Java URLEncoder, caracteres encodes courants, encodage de formulaires, parametres de requete API, debogage du double encodage.