URL Encoding: Haciendo URLs Seguras para la Web
Has copiado una URL y viste %20 donde debería haber un espacio, o %C3%A9 donde había un carácter acentuado. Eso es URL encoding (también llamado percent-encoding), y existe porque las URLs solo pueden contener un conjunto específico de caracteres ASCII.
Por Qué las URLs Necesitan Encoding
Las URLs tienen caracteres reservados con significados especiales:
| Carácter | Significado en URL |
|---|---|
/ | Separador de ruta |
? | Inicio del query string |
& | Separador de parámetros query |
= | Separador clave-valor |
# | Identificador de fragmento |
: | Separador de esquema (http:) |
@ | Separador de info del usuario |
Si tus datos contienen estos caracteres, debes codificarlos para evitar ambigüedad. De lo contrario el navegador no puede saber si & es parte de tus datos o un separador de query.
Cómo Funciona el Encoding
Cada carácter inseguro se reemplaza con % seguido de su valor hex de dos dígitos:
| Carácter | Codificado | Valor Hex |
|---|---|---|
| Espacio | %20 | 0x20 |
! | %21 | 0x21 |
# | %23 | 0x23 |
& | %26 | 0x26 |
+ | %2B | 0x2B |
/ | %2F | 0x2F |
é | %C3%A9 | UTF-8: 0xC3 0xA9 |
Los caracteres no-ASCII (acentos, CJK, emoji) primero se convierten a bytes UTF-8, luego cada byte se percent-encodes.
JavaScript: encodeURI vs encodeURIComponent
Esta es la API más confusa de JavaScript:
// encodeURI — codifica una URL COMPLETA
// NO codifica: : / ? # [ ] @ ! $ & ' ( ) * + , ; =
encodeURI('https://example.com/path with spaces?q=hello world')
// "https://example.com/path%20with%20spaces?q=hello%20world"
// encodeURIComponent — codifica un COMPONENTE (valor)
// SÍ codifica: : / ? # @ ! $ & ' ( ) * + , ; =
encodeURIComponent('price=10¤cy=USD')
// "price%3D10%26currency%3DUSD"Regla de oro:
- Usa
encodeURIComponent()para valores de parámetros query - Usa
encodeURI()solo para codificar una URL completa que ya tiene la estructura correcta - Mejor aún: usa las APIs
URLyURLSearchParams— manejan el encoding automáticamente
La Forma Moderna: URL y URLSearchParams
// Construye URLs de forma segura — sin encoding manual
const url = new URL('https://api.example.com/search');
url.searchParams.set('q', 'café & croissant');
url.searchParams.set('page', '1');
console.log(url.toString());
// "https://api.example.com/search?q=caf%C3%A9+%26+croissant&page=1"
// Parsear URLs existentes
const parsed = new URL('https://example.com/path?name=Jo%C3%A3o');
console.log(parsed.searchParams.get('name'));
// "João" — decodificado automáticamenteErrores Comunes de Encoding
Double encoding: Codificar una cadena ya codificada. %20 se convierte en %2520. Pasa cuando llamas encodeURIComponent en un valor que ya fue codificado.
No codificar: Pasar input crudo del usuario en URLs. Si el nombre de alguien es "O'Brien & Sons", tu URL se rompe.
Usar + para espacios: En query strings, + significa espacio (del encoding de formularios HTML). Pero en segmentos de ruta, + es un signo de más literal. %20 siempre significa espacio en todas partes.
# Python
from urllib.parse import quote, unquote, urlencode
quote('café & croissant') # 'caf%C3%A9%20%26%20croissant'
unquote('caf%C3%A9') # 'café'
# Construir query strings
urlencode({'q': 'hello world', 'lang': 'pt'})
# 'q=hello+world&lang=pt'// Go
import "net/url"
encoded := url.QueryEscape("café & croissant")
// "caf%C3%A9+%26+croissant"
decoded, _ := url.QueryUnescape(encoded)
// "café & croissant"Cuándo Codificar Qué
| Parte de la URL | Codificar Con | Ejemplo |
|---|---|---|
| URL completa | encodeURI() / new URL() | https://example.com/my%20page |
| Valor de param query | encodeURIComponent() / URLSearchParams | ?q=caf%C3%A9 |
| Segmento de ruta | encodeURIComponent() | /users/Jo%C3%A3o |
| Datos de formulario | application/x-www-form-urlencoded | name=Jo%C3%A3o&city=S%C3%A3o+Paulo |
Codifica/decodifica ahora: Codificador/Decodificador URL — pega cualquier texto o URL, codifica o decodifica instantáneamente.