URL Encode JavaScript — encodeURIComponent()
Utilisez le Encodeur d'URL en ligne gratuit directement dans votre navigateur — sans installation.
Essayer Encodeur d'URL en ligne en ligne →Lorsque vous construisez une URL de recherche, passez un chemin de redirection comme paramètre de query, ou montez une requête d'autorisation OAuth, les caractères spéciaux comme &, = et les espaces vont silencieusement corrompre l'URL si vous ne les encodez pas au préalable. JavaScript offre trois approches natives — encodeURIComponent(), encodeURI() et URLSearchParams— chacune conçue pour un cas d'usage différent, et choisir la mauvaise est la cause première de la plupart des bugs d'encodage que j'ai rencontrés lors de revues de code. Pour un encodage rapide sans écrire de code, l'Encodeur URL de ToolDeck le gère instantanément dans le navigateur. Ce guide couvre les trois approches en profondeur (JavaScript ES2015+ / Node.js 10+) : quand utiliser chacune, comment elles diffèrent pour les espaces et les caractères réservés, des exemples réels avec Fetch et les API, l'usage en ligne de commande, et les quatre erreurs qui provoquent les bugs de production les plus subtils.
- ✓encodeURIComponent() est le bon choix pour encoder des valeurs de paramètres individuels — il encode tous les caractères sauf A–Z, a–z, 0–9 et - _ . ! ~ * ' ( )
- ✓encodeURI() encode une URL complète en préservant les caractères structurels (/ ? # & = :) — ne l'utilisez jamais pour des valeurs individuelles
- ✓URLSearchParams encode automatiquement les paires clé-valeur au format application/x-www-form-urlencoded, où les espaces deviennent + au lieu de %20
- ✓Le double encodage est le bug de production le plus courant : encodeURIComponent(encodeURIComponent(value)) transforme %20 en %2520
- ✓La bibliothèque qs gère nativement les objets imbriqués et les tableaux dans les query strings — URLSearchParams de la stdlib ne le fait pas
Qu'est-ce que l'encodage d'URL ?
L'encodage d'URL (formellement appelé encodage pourcent, défini dans la RFC 3986) convertit les caractères non autorisés ou ayant une signification spéciale dans une URL en une représentation sûre. Chaque octet non sûr est remplacé par un signe pourcent suivi de deux chiffres hexadécimaux — le code ASCII du caractère. Un espace devient %20, une esperluette devient %26, une barre oblique devient %2F.
Les caractères toujours sûrs et jamais encodés sont appelés caractères non réservés : les lettres A–Z et a–z, les chiffres 0–9, et les quatre symboles - _ . ~. Tout le reste doit être encodé lorsqu'utilisé comme donnée, ou a un rôle structurel dans l'URL (comme / séparant les segments de chemin ou &séparant les paramètres de query). La conséquence pratique : un nom de produit comme “Clavier Sans Fil & Souris” dans un paramètre de query détruit la structure de l'URL s'il est passé brut.
https://shop.example.com/search?q=Wireless Keyboard & Mouse&category=peripherals
https://shop.example.com/search?q=Wireless%20Keyboard%20%26%20Mouse&category=peripherals
encodeURIComponent() — La bonne fonction pour les paramètres de query
encodeURIComponent()est le moteur de l'encodage d'URL en JavaScript. Elle encode tous les caractères saufl'ensemble non réservé (A–Z, a–z, 0–9, - _ . ! ~ * ' ( )). De manière critique, elle encode tous les caractères ayant une signification structurelle dans les URL — &, =, ?, #, / — ce qui la rend sûre pour une utilisation dans les valeursde paramètres. Aucune importation n'est nécessaire ; c'est une fonction globale disponible dans tous les environnements JavaScript.
Exemple minimal fonctionnel
// Encode a search query parameter that contains special characters
const searchQuery = 'Wireless Keyboard & Mouse'
const filterStatus = 'in-stock'
const maxPrice = '149.99'
const searchUrl = `https://shop.example.com/products?` +
`q=${encodeURIComponent(searchQuery)}` +
`&status=${encodeURIComponent(filterStatus)}` +
`&maxPrice=${encodeURIComponent(maxPrice)}`
console.log(searchUrl)
// https://shop.example.com/products?q=Wireless%20Keyboard%20%26%20Mouse&status=in-stock&maxPrice=149.99Encoder une URL de redirection comme paramètre de query
// The redirect destination is itself a URL — it must be fully encoded
// or the outer URL parser will misinterpret its ? and & as its own
const redirectAfterLogin = 'https://dashboard.internal/reports?view=weekly&team=platform'
const loginUrl = `https://auth.company.com/login?next=${encodeURIComponent(redirectAfterLogin)}`
console.log(loginUrl)
// https://auth.company.com/login?next=https%3A%2F%2Fdashboard.internal%2Freports%3Fview%3Dweekly%26team%3Dplatform
// Decoding on the receiving end
const params = new URLSearchParams(window.location.search)
const next = params.get('next') // Automatically decoded
const nextUrl = new URL(next!) // Safe to parse
console.log(nextUrl.hostname) // dashboard.internalEncoder des caractères non-ASCII et Unicode
// encodeURIComponent handles Unicode natively in all modern environments
// Each UTF-8 byte of the character is percent-encoded
const customerName = 'Dupont, Thomas'
const productTitle = '東京 wireless adapter'
const reviewText = 'Très bien — fonctionne parfaitement'
console.log(encodeURIComponent(customerName))
// Dupont%2C%20Thomas
console.log(encodeURIComponent(productTitle))
// %E6%9D%B1%E4%BA%AC%20wireless%20adapter
console.log(encodeURIComponent(reviewText))
// Tr%C3%A8s%20bien%20%E2%80%94%20fonctionne%20parfaitement
// Decoding back
console.log(decodeURIComponent('Dupont%2C%20Thomas'))
// Dupont, ThomasencodeURIComponent()utilise l'encodage interne UTF-16 du moteur JavaScript, puis encode chaque octet UTF-8 du caractère séparément. Un caractère comme ü (U+00FC) s'encode en %C3%BCcar sa représentation UTF-8 est de deux octets : 0xC3 et 0xBC. C'est correct et conforme au standard URI — les serveurs sont censés décoder la séquence d'octets UTF-8 pour retrouver le point de code original.Fonctions d'encodage d'URL en JavaScript — Référence des caractères
Les trois approches d'encodage natives diffèrent précisément dans les caractères qu'elles encodent. Le tableau ci-dessous montre la sortie pour les caractères les plus souvent problématiques :
| Caractère | Rôle dans l'URL | encodeURIComponent() | encodeURI() | URLSearchParams |
|---|---|---|---|---|
| Space | séparateur de mots | %20 | %20 | + |
| & | séparateur de paramètres | %26 | conservé | %26 |
| = | clé=valeur | %3D | conservé | %3D |
| + | espace encodé (form) | %2B | %2B | %2B |
| ? | début de query | %3F | conservé | %3F |
| # | fragment | %23 | conservé | %23 |
| / | séparateur de chemin | %2F | conservé | %2F |
| : | schéma / port | %3A | conservé | %3A |
| @ | séparateur d'auth | %40 | conservé | %40 |
| % | pourcent littéral | %25 | %25 | %25 |
| ~ | non réservé | conservé | conservé | conservé |
La colonne critique est encodeURIComponent() versus encodeURI() pour & et = : encodeURI()les laisse intacts, ce qui est correct lors de l'encodage d'une URL complète, mais catastrophique lors de l'encodage d'une valeur qui contient ces caractères.
encodeURI() — Quand préserver la structure de l'URL
encodeURI() est conçue pour encoder une URL complète— elle préserve tous les caractères qui sont des parties structurelles valides d'une URI : le schéma (https://), l'hôte, les séparateurs de chemin, les délimiteurs de query et l'identifiant de fragment. Utilisez-la quand vous recevez une URL qui peut contenir des espaces ou des caractères non-ASCII dans ses segments de chemin, mais que vous devez conserver sa structure intacte.
Assainissement d'une URL fournie par l'utilisateur
// A URL pasted from a document with spaces in the path and non-ASCII chars const rawUrl = 'https://cdn.example.com/assets/product images/München chair.png' const safeUrl = encodeURI(rawUrl) console.log(safeUrl) // https://cdn.example.com/assets/product%20images/M%C3%BCnchen%20chair.png // encodeURIComponent would break it — it encodes the :// and all / characters const broken = encodeURIComponent(rawUrl) console.log(broken) // https%3A%2F%2Fcdn.example.com%2Fassets%2Fproduct%20images%2FM%C3%BCnchen%20chair.png // ↑ Not a valid URL — the scheme and slashes are destroyed
URL est généralement un meilleur choix que encodeURI()pour gérer les chaînes d'URL fournies par l'utilisateur — il normalise l'URL, valide la structure et vous offre une API propre pour accéder à chaque composant. Réservez encodeURI()aux cas où vous avez besoin d'un résultat sous forme de chaîne et savez déjà que l'entrée est structurellement une URL valide.URLSearchParams — L'approche moderne pour les query strings
URLSearchParamsest la façon idiomatique de construire et d'analyser les query strings en JavaScript moderne. Il est disponible globalement dans tous les navigateurs modernes et Node.js 10+, et gère l'encodage automatiquement — vous travaillez avec des paires clé-valeur simples et il produit la sortie correcte. Un détail important : il suit la spécification application/x-www-form-urlencoded, qui encode les espaces comme + plutôt que %20. C'est correct et largement supporté, mais vous devez en être conscient quand votre serveur attend un format spécifique.
Construction d'une URL de requête de recherche
// Building a search API URL with multiple parameters
const filters = {
query: 'standing desk',
category: 'office-furniture',
minPrice: '200',
maxPrice: '800',
inStock: 'true',
sortBy: 'price_asc',
}
const params = new URLSearchParams(filters)
const apiUrl = `https://api.example.com/v2/products?${params}`
console.log(apiUrl)
// https://api.example.com/v2/products?query=standing+desk&category=office-furniture&minPrice=200&maxPrice=800&inStock=true&sortBy=price_asc
// Appending additional params after construction
params.append('page', '2')
params.append('tag', 'ergonomic & adjustable')
console.log(params.toString())
// query=standing+desk&...&tag=ergonomic+%26+adjustableAnalyse d'une query string entrante
// Both browser (window.location.search) and Node.js (req.url) scenarios
function parseWebhookCallbackUrl(rawSearch: string) {
const params = new URLSearchParams(rawSearch)
return {
eventId: params.get('event_id'), // null if missing
timestamp: Number(params.get('ts')),
signature: params.get('sig'),
redirectUrl: params.get('redirect'), // Automatically decoded
tags: params.getAll('tag'), // Handles repeated keys
}
}
const callbackQuery = '?event_id=evt_9c2f&ts=1717200000&sig=sha256%3Dabc123&redirect=https%3A%2F%2Fdashboard.internal%2F&tag=payment&tag=webhook'
const parsed = parseWebhookCallbackUrl(callbackQuery)
console.log(parsed.redirectUrl) // https://dashboard.internal/
console.log(parsed.tags) // ['payment', 'webhook']Comment encoder les paramètres d'URL dans les requêtes Fetch JavaScript
L'endroit le plus courant où l'encodage d'URL apparaît dans le code de production est à l'intérieur des appels fetch()— soit lors de la construction de l'URL de la requête, soit lors de l'envoi de données de formulaire dans le corps de la requête. Chaque scénario a sa propre approche correcte.
Requête GET — encodage des paramètres de query
async function searchInventory(params: {
sku?: string
warehouse: string
minStock: number
updatedAfter?: Date
}): Promise<{ items: unknown[]; total: number }> {
const searchParams = new URLSearchParams()
if (params.sku) searchParams.set('sku', params.sku)
searchParams.set('warehouse', params.warehouse)
searchParams.set('min_stock', String(params.minStock))
if (params.updatedAfter) searchParams.set('updated_after', params.updatedAfter.toISOString())
const url = `https://inventory.internal/api/items?${searchParams}`
const res = await fetch(url, {
headers: {
'Authorization': `Bearer ${process.env.INVENTORY_API_KEY}`,
'Accept': 'application/json',
},
})
if (!res.ok) {
throw new Error(`Inventory API ${res.status}: ${await res.text()}`)
}
return res.json()
}
const results = await searchInventory({
warehouse: 'eu-west-1',
minStock: 10,
updatedAfter: new Date('2025-01-01'),
})
console.log(`Found ${results.total} items`)Requête POST — encodage du corps d'un formulaire en URL
// application/x-www-form-urlencoded POST — used by OAuth token endpoints,
// legacy form-submission APIs, and some webhook providers
async function requestOAuthToken(
clientId: string,
clientSecret: string,
code: string,
redirectUri: string,
): Promise<{ access_token: string; expires_in: number }> {
const body = new URLSearchParams({
grant_type: 'authorization_code',
client_id: clientId,
client_secret: clientSecret,
code,
redirect_uri: redirectUri, // URLSearchParams encodes this automatically
})
const res = await fetch('https://oauth.provider.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: body.toString(),
// body: body — also works directly in modern environments (Fetch spec accepts URLSearchParams)
})
if (!res.ok) {
const err = await res.json()
throw new Error(`OAuth error: ${err.error_description ?? err.error}`)
}
return res.json()
}Quand vous avez besoin de tester ou déboguer une URL encodée sans configurer de script, collez la valeur brute directement dans l' Encodeur URL — il encode et décode instantanément, vous montrant exactement ce que le navigateur et le serveur verront. Utile pour inspecter les URI de redirection OAuth, les URL de callback de webhooks et les paramètres de requêtes signées CDN.
Encodage d'URL en ligne de commande avec Node.js et Shell
Pour les scripts shell, les pipelines CI, ou le débogage rapide, plusieurs approches en ligne de commande fonctionnent sans écrire un script complet.
# ── Node.js one-liners — cross-platform (macOS, Linux, Windows) ────────
# encodeURIComponent — encode a single value
node -e "console.log(encodeURIComponent(process.argv[1]))" "Wireless Keyboard & Mouse"
# Wireless%20Keyboard%20%26%20Mouse
# Build a complete query string
node -e "console.log(new URLSearchParams(JSON.parse(process.argv[1])).toString())" '{"q":"standing desk","category":"office-furniture","page":"1"}'
# q=standing+desk&category=office-furniture&page=1
# Decode a percent-encoded string
node -e "console.log(decodeURIComponent(process.argv[1]))" "Wireless%20Keyboard%20%26%20Mouse"
# Wireless Keyboard & Mouse
# ── curl — automatic encoding ───────────────────────────────────────────
# curl --data-urlencode encodes values automatically in GET and POST
curl -G "https://api.example.com/search" --data-urlencode "q=Wireless Keyboard & Mouse" --data-urlencode "category=office furniture"
# ── Python one-liner (available on most systems) ─────────────────────────
python3 -c "from urllib.parse import quote; print(quote(input(), safe=''))"
# (type the string and press Enter)
# ── jq + bash: encode every value in a JSON object ───────────────────────
echo '{"q":"hello world","tag":"node & express"}' | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); console.log(new URLSearchParams(d).toString())"
# q=hello+world&tag=node+%26+expressAlternative haute performance : qs
Le URLSearchParams natif ne prend pas en charge les objets imbriqués ni les tableaux — la forme des query strings utilisée par de nombreuses API et frameworks. La bibliothèque qs (plus de 30 millions de téléchargements hebdomadaires sur npm) gère toute la gamme des patterns de query strings utilisés dans la pratique : objets imbriqués avec notation entre crochets (filters[status]=active), clés répétées, encodeurs personnalisés et formats de sérialisation de tableaux configurables.
npm install qs # or pnpm add qs
import qs from 'qs'
// URLSearchParams cannot represent this structure natively
const reportFilters = {
dateRange: {
from: '2025-01-01',
to: '2025-03-31',
},
status: ['published', 'archived'],
author: { id: 'usr_4f2a9c1b', role: 'editor' },
workspace: 'ws-platform-eu',
}
// qs produces bracket-notation query strings used by Express, Rails, Django REST
const query = qs.stringify(reportFilters, { encode: true })
console.log(query)
// dateRange%5Bfrom%5D=2025-01-01&dateRange%5Bto%5D=2025-03-31&status%5B0%5D=published&status%5B1%5D=archived&author%5Bid%5D=usr_4f2a9c1b&author%5Brole%5D=editor&workspace=ws-platform-eu
// Human-readable (no encoding) — useful for debugging
console.log(qs.stringify(reportFilters, { encode: false }))
// dateRange[from]=2025-01-01&dateRange[to]=2025-03-31&status[0]=published&status[1]=archived...
// Parsing back
const parsed = qs.parse(query)
console.log(parsed.dateRange) // { from: '2025-01-01', to: '2025-03-31' }
console.log(parsed.status) // ['published', 'archived']Pour les paramètres simples clé-valeur, URLSearchParams est toujours le bon choix — il est natif, sans surcoût et universellement supporté. Faites appel à qs uniquement quand vous avez besoin de structures imbriquées, de formats de sérialisation de tableaux autres que les clés répétées, ou quand vous vous intégrez avec un framework back-end qui attend des query strings en notation entre crochets.
Erreurs courantes
J'ai vu ces quatre erreurs à répétition dans des bases de code de production — la plupart sont des échecs silencieux qui ne surgissent que lorsqu'une valeur contient un caractère spécial, ce qui est exactement le type de bug qui passe au travers des tests unitaires et n'apparaît qu'avec de vraies données utilisateur.
Erreur 1 — Utiliser encodeURI() pour des valeurs de paramètres de query
Problème : encodeURI() n'encode pas &, = ni +. Quand une valeur contient ces caractères, ils sont interprétés comme de la syntaxe de query string, divisant ou écrasant silencieusement les paramètres. Solution : utilisez toujours encodeURIComponent() pour les valeurs individuelles.
// ❌ encodeURI does not encode & and = in the value
// "plan=pro&promo=SAVE20" is treated as two separate params
const planName = 'Pro Plan (save=20% & free trial)'
const url = `/checkout?plan=${encodeURI(planName)}`
// /checkout?plan=Pro%20Plan%20(save=20%%20&%20free%20trial)
// ↑ & breaks the query string// ✅ encodeURIComponent encodes & and = safely
const planName = 'Pro Plan (save=20% & free trial)'
const url = `/checkout?plan=${encodeURIComponent(planName)}`
// /checkout?plan=Pro%20Plan%20(save%3D20%25%20%26%20free%20trial)
// ↑ = and & are both encodedErreur 2 — Double encodage d'une chaîne déjà encodée
Problème : Appeler encodeURIComponent() sur une valeur déjà encodée en pourcent transforme le % en %25, donc %20 devient %2520. Le serveur décode une fois et reçoit un littéral %20 au lieu d'un espace. Solution : décodez d'abord, puis réencodez, ou assurez-vous que la valeur n'est jamais encodée deux fois.
// ❌ encodedParam already contains %20 — encoding again produces %2520
const encodedParam = 'Berlin%20Office'
const url = `/api/locations/${encodeURIComponent(encodedParam)}`
// /api/locations/Berlin%2520Office
// Server sees: "Berlin%20Office" (a literal percent-twenty, not a space)// ✅ Decode first if the value may already be encoded
const maybeEncoded = 'Berlin%20Office'
const clean = decodeURIComponent(maybeEncoded) // 'Berlin Office'
const url = `/api/locations/${encodeURIComponent(clean)}`
// /api/locations/Berlin%20Office — correctErreur 3 — Ne pas tenir compte de la différence + / %20 entre URLSearchParams et encodeURIComponent
Problème : URLSearchParams encode les espaces comme + (application/x-www-form-urlencoded), tandis que encodeURIComponent() utilise %20. Mélanger les deux dans la même URL — par exemple, ajouter une chaîne pré-encodée à une sortie URLSearchParams — produit un encodage incohérent qui déroute certains parseurs. Solution : choisissez une approche et utilisez-la de manière cohérente dans toute la fonction de construction d'URL.
// ❌ Mixed: URLSearchParams uses + for spaces, but we're appending
// a manually-encoded segment that uses %20
const base = new URLSearchParams({ category: 'office furniture' })
const extra = `sort=${encodeURIComponent('price asc')}`
const url = `/api/products?${base}&${extra}`
// /api/products?category=office+furniture&sort=price%20asc
// ↑ two different space encodings in the same URL// ✅ Use URLSearchParams exclusively — consistent encoding throughout
const params = new URLSearchParams({
category: 'office furniture',
sort: 'price asc',
})
const url = `/api/products?${params}`
// /api/products?category=office+furniture&sort=price+ascErreur 4 — Oublier d'encoder les segments de chemin contenant des barres obliques
Problème : Un identifiant de ressource comme un chemin de fichier (reports/2025/q1.pdf) utilisé comme segment de chemin REST contient des caractères / que le routeur du serveur interprète comme des séparateurs de chemin, routant vers un endpoint inexistant. Solution : utilisez toujours encodeURIComponent() pour les segments de chemin qui peuvent contenir des barres obliques.
// ❌ The file path contains / — the server receives a 3-segment path
// instead of a single resource ID
const filePath = 'reports/2025/q1-financials.pdf'
const url = `https://storage.example.com/objects/${filePath}`
// https://storage.example.com/objects/reports/2025/q1-financials.pdf
// → Server routes to /objects/:year/:filename — 404 or wrong resource// ✅ encodeURIComponent encodes / as %2F — single path segment
const filePath = 'reports/2025/q1-financials.pdf'
const url = `https://storage.example.com/objects/${encodeURIComponent(filePath)}`
// https://storage.example.com/objects/reports%2F2025%2Fq1-financials.pdf
// → Server receives the full file path as one resource identifierMéthodes d'encodage d'URL en JavaScript — Comparaison rapide
| Méthode | Encode les espaces comme | Encode & = ? | Encode # / : | Cas d'usage | Nécessite installation |
|---|---|---|---|---|---|
| encodeURIComponent() | %20 | ✅ oui | ✅ oui | Encoder des valeurs de paramètres individuels | No |
| encodeURI() | %20 | ❌ non | ❌ non | Assainir une chaîne d'URL complète | No |
| URLSearchParams | + | ✅ oui | ✅ oui | Construire et analyser des query strings | No |
| Constructeur URL | auto par composant | auto | auto | Construire et normaliser des URL complètes | No |
| bibliothèque qs | %20 (configurable) | ✅ oui | ✅ oui | Objets imbriqués et tableaux dans les query strings | npm install qs |
Pour la grande majorité des cas, le choix se réduit à trois scénarios. Utilisez URLSearchParamslors de la construction de query strings à plusieurs paramètres à partir de données structurées — c'est l'option la plus sûre et la plus lisible. Utilisez encodeURIComponent() pour encoder une seule valeur dans une URL avec template literal, pour les segments de chemin, ou pour les valeurs dans des systèmes qui attendent %20 plutôt que + pour les espaces (comme les URL signées AWS S3). Faites appel à qs uniquement quand votre query string porte des objets imbriqués ou des tableaux que URLSearchParams ne peut pas représenter nativement.
Questions fréquentes
Outils associés
Pour encoder ou décoder en un clic sans écrire de code, collez votre chaîne directement dans l' Encodeur URL — il gère l'encodage pourcent et le décodage instantanément dans votre navigateur, avec la sortie encodée prête à copier dans un appel fetch ou dans le terminal.
Alex is a front-end and Node.js developer with extensive experience building web applications and developer tooling. He is passionate about web standards, browser APIs, and the JavaScript ecosystem. In his spare time he contributes to open-source projects and writes about modern JavaScript patterns, performance optimisation, and everything related to the web platform.
Sophie is a full-stack developer focused on TypeScript across the entire stack — from React frontends to Express and Fastify backends. She has a particular interest in type-safe API design, runtime validation, and the patterns that make large JavaScript codebases stay manageable. She writes about TypeScript idioms, Node.js internals, and the ever-evolving JavaScript module ecosystem.