Codificación/Decodificación URL

Herramienta para codificar y decodificar URL, maneja caracteres especiales en URLs

Resumen de la herramienta: Herramienta de Codificación y Decodificación URL

La codificación URL (codificación porcentual) es un método de codificación utilizado para transferir de forma segura caracteres que tienen significado especial en URLs o caracteres fuera del conjunto de caracteres ASCII. Se utiliza ampliamente en desarrollo web, comunicación API, envío de formularios y otros escenarios.

¿Qué es Herramienta de Codificación y Decodificación URL?

Herramienta de Codificación y Decodificación URL codifica o decodifica parámetros URL para evitar problemas con caracteres especiales.

Cómo usarlo

  1. Pega la URL o parámetros.
  2. Elige modo codificar/decodificar.
  3. Copia el resultado.

Casos de uso comunes

  • Transmisión segura de parámetros
  • Depurar caracteres especiales en URLs
  • Validación de parámetros en APIs

❓ Preguntas frecuentes

P1: ¿Salida ilegible?
R: Asegura UTF-8 y evita doble codificación.

P2: ¿Cómo maneja espacios?
R: Se convierten en %20 o + según el modo.

P3: ¿Procesamiento en lote?
R: Usa entrada multilínea si está disponible.

✨ Características Principales

  • 🔄 Conversión Bidireccional: Compatible con codificación y decodificación URL
  • 🌐 Soporte Multiidioma: Compatible con caracteres Unicode como español, chino, emojis
  • Conversión en Tiempo Real: Muestra resultados de conversión al mismo tiempo que la entrada
  • 📋 Copia con Un Clic: Los resultados de conversión se pueden copiar directamente
  • 🔧 Detección de Errores: Detecta automáticamente formatos de codificación inválidos

📖 Ejemplos de Uso

Codificación URL en Español

URL de Entrada:

https://www.example.com/búsqueda?q=ToolMi

Resultado de Codificación:

https://www.example.com/b%C3%BAsqueda?q=ToolMi

Codificación de Parámetros de Consulta

Parámetros de Entrada:

nombre=Juan Pérez&[email protected]&mensaje=¡Hola!

Resultado de Codificación:

nombre=Juan%20P%C3%A9rez&email=juan%40example.com&mensaje=%C2%A1Hola%21

Codificación de Caracteres Especiales

Texto de Entrada:

Hello World! #caracteres especiales @símbolos &ampersand

Resultado de Codificación:

Hello%20World%21%20%23caracteres%20especiales%20%40s%C3%ADmbolos%20%26ampersand

🎯 Escenarios de Aplicación

1. Desarrollo Web

Envío de formularios y construcción de URLs:

// Codificación URL de datos de formulario
const codificarDatosFormulario = (datosFormulario) => {
  const parametros = new URLSearchParams();
  
  for (const [clave, valor] of Object.entries(datosFormulario)) {
    parametros.append(clave, valor);
  }
  
  return parametros.toString();
};

// Ejemplo de uso
const datosFormulario = {
  nombre: 'Juan Pérez',
  email: '[email protected]',
  mensaje: 'Contenido de consulta.',
  categoria: 'Soporte'
};

const datosCodificados = codificarDatosFormulario(datosFormulario);
console.log('Datos de formulario codificados:', datosCodificados);
// nombre=Juan%20P%C3%A9rez&email=juan%40example.com...

// Construcción dinámica de URL
const construirURLBusqueda = (urlBase, parametrosBusqueda) => {
  const url = new URL(urlBase);
  
  for (const [clave, valor] of Object.entries(parametrosBusqueda)) {
    url.searchParams.set(clave, valor);
  }
  
  return url.toString();
};

// Construcción de URL de búsqueda
const urlBusqueda = construirURLBusqueda('https://www.example.com/buscar', {
  q: 'Herramientas JavaScript',
  categoria: 'Programación',
  orden: 'más reciente'
});

console.log('URL de búsqueda:', urlBusqueda);
// https://www.example.com/buscar?q=Herramientas%20JavaScript&categoria=Programaci%C3%B3n...

2. Comunicación API

Manejo de parámetros en API RESTful:

// Clase cliente API
class ClienteAPI {
  constructor(urlBase) {
    this.urlBase = urlBase;
  }

  // Manejo de parámetros de consulta en solicitudes GET
  async get(endpoint, parametros = {}) {
    const url = new URL(`${this.urlBase}${endpoint}`);
    
    // Codificar parámetros de forma segura
    for (const [clave, valor] of Object.entries(parametros)) {
      if (valor !== null && valor !== undefined) {
        url.searchParams.set(clave, valor);
      }
    }

    try {
      const respuesta = await fetch(url.toString());
      
      if (!respuesta.ok) {
        throw new Error(`Error HTTP! estado: ${respuesta.status}`);
      }
      
      return await respuesta.json();
    } catch (error) {
      console.error('Error de solicitud API:', error);
      throw error;
    }
  }

  // Envío de datos de formulario en solicitudes POST
  async post(endpoint, datos) {
    const url = `${this.urlBase}${endpoint}`;
    
    // Codificar como datos de formulario
    const datosFormulario = new URLSearchParams();
    for (const [clave, valor] of Object.entries(datos)) {
      datosFormulario.append(clave, valor);
    }

    try {
      const respuesta = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: datosFormulario.toString()
      });

      if (!respuesta.ok) {
        throw new Error(`Error HTTP! estado: ${respuesta.status}`);
      }

      return await respuesta.json();
    } catch (error) {
      console.error('Error POST de API:', error);
      throw error;
    }
  }

  // Carga de archivos
  async subirArchivo(endpoint, archivo, datosAdicionales = {}) {
    const url = `${this.urlBase}${endpoint}`;
    const datosFormulario = new FormData();
    
    // Agregar archivo
    datosFormulario.append('archivo', archivo);
    
    // Agregar datos adicionales (se codifican automáticamente)
    for (const [clave, valor] of Object.entries(datosAdicionales)) {
      datosFormulario.append(clave, valor);
    }

    try {
      const respuesta = await fetch(url, {
        method: 'POST',
        body: datosFormulario // Content-Type se establece automáticamente
      });

      if (!respuesta.ok) {
        throw new Error(`Error HTTP! estado: ${respuesta.status}`);
      }

      return await respuesta.json();
    } catch (error) {
      console.error('Error de carga de archivo:', error);
      throw error;
    }
  }
}

// Ejemplo de uso
const clienteApi = new ClienteAPI('https://api.example.com');

// Llamada API de búsqueda
clienteApi.get('/buscar', {
  q: 'Librerías JavaScript',
  categoria: 'Programación',
  pagina: 1,
  limite: 20
}).then(resultados => {
  console.log('Resultados de búsqueda:', resultados);
}).catch(error => {
  console.error('Error de búsqueda:', error);
});

// Registro de usuario
clienteApi.post('/usuarios', {
  nombre: 'María García',
  email: '[email protected]',
  bio: 'Desarrolladora frontend.'
}).then(usuario => {
  console.log('Usuario creado exitosamente:', usuario);
}).catch(error => {
  console.error('Error al crear usuario:', error);
});

3. Gestión de Historial del Navegador

Gestión de estado URL en SPA:

// Gestor de estado URL
class GestorEstadoURL {
  constructor() {
    this.estadoActual = this.analizarURLActual();
    
    // Soporte para botones atrás/adelante del navegador
    window.addEventListener('popstate', (evento) => {
      this.estadoActual = evento.state || this.analizarURLActual();
      this.alCambiarEstado(this.estadoActual);
    });
  }

  // Analizar estado desde URL actual
  analizarURLActual() {
    const url = new URL(window.location.href);
    const estado = {};
    
    // Obtener parámetros de consulta como estado
    for (const [clave, valor] of url.searchParams.entries()) {
      estado[clave] = decodeURIComponent(valor);
    }
    
    return estado;
  }

  // Reflejar estado en URL
  actualizarURL(nuevoEstado, titulo = '') {
    const url = new URL(window.location.href);
    
    // Limpiar parámetros de consulta existentes
    url.search = '';
    
    // Establecer nuevo estado como parámetros de consulta
    for (const [clave, valor] of Object.entries(nuevoEstado)) {
      if (valor !== null && valor !== undefined && valor !== '') {
        url.searchParams.set(clave, valor);
      }
    }

    // Actualizar historial del navegador
    window.history.pushState(nuevoEstado, titulo, url.toString());
    this.estadoActual = nuevoEstado;
    this.alCambiarEstado(nuevoEstado);
  }

  // Reemplazar estado (no agregar al historial)
  reemplazarURL(nuevoEstado, titulo = '') {
    const url = new URL(window.location.href);
    url.search = '';
    
    for (const [clave, valor] of Object.entries(nuevoEstado)) {
      if (valor !== null && valor !== undefined && valor !== '') {
        url.searchParams.set(clave, valor);
      }
    }

    window.history.replaceState(nuevoEstado, titulo, url.toString());
    this.estadoActual = nuevoEstado;
  }

  // Callback al cambiar estado
  alCambiarEstado(estado) {
    console.log('Estado URL cambiado:', estado);
    // Actualizar estado de la aplicación
    this.actualizarEstadoAplicacion(estado);
  }

  // Actualizar estado de la aplicación
  actualizarEstadoAplicacion(estado) {
    // Actualizar formulario de búsqueda
    if (estado.q) {
      const entradaBusqueda = document.getElementById('entradaBusqueda');
      if (entradaBusqueda) {
        entradaBusqueda.value = estado.q;
      }
    }

    // Actualizar filtros
    if (estado.categoria) {
      const selectCategoria = document.getElementById('selectCategoria');
      if (selectCategoria) {
        selectCategoria.value = estado.categoria;
      }
    }

    // Actualizar paginación
    if (estado.pagina) {
      this.actualizarPaginacion(parseInt(estado.pagina));
    }
  }

  // Actualizar estado de búsqueda
  actualizarEstadoBusqueda(consulta, categoria = '', pagina = 1) {
    const nuevoEstado = {
      q: consulta,
      categoria: categoria,
      pagina: pagina > 1 ? pagina : undefined
    };

    this.actualizarURL(nuevoEstado, `Búsqueda: ${consulta}`);
  }

  // Obtener estado actual
  obtenerEstadoActual() {
    return { ...this.estadoActual };
  }

  // Obtener parámetro específico
  obtenerParametro(clave, valorPorDefecto = '') {
    return this.estadoActual[clave] || valorPorDefecto;
  }
}

// Ejemplo de uso
const gestorEstadoURL = new GestorEstadoURL();

// Procesamiento de formulario de búsqueda
document.getElementById('formularioBusqueda').addEventListener('submit', (evento) => {
  evento.preventDefault();
  
  const datosFormulario = new FormData(evento.target);
  const consulta = datosFormulario.get('q');
  const categoria = datosFormulario.get('categoria');
  
  // Actualizar estado URL
  gestorEstadoURL.actualizarEstadoBusqueda(consulta, categoria, 1);
  
  // Ejecutar búsqueda
  realizarBusqueda(consulta, categoria, 1);
});

// Procesamiento de paginación
const manejarCambioPagina = (pagina) => {
  const estadoActual = gestorEstadoURL.obtenerEstadoActual();
  gestorEstadoURL.actualizarEstadoBusqueda(
    estadoActual.q || '',
    estadoActual.categoria || '',
    pagina
  );
  
  realizarBusqueda(estadoActual.q, estadoActual.categoria, pagina);
};

// Función de ejecución de búsqueda
const realizarBusqueda = async (consulta, categoria, pagina) => {
  try {
    const resultados = await clienteApi.get('/buscar', {
      q: consulta,
      categoria: categoria,
      pagina: pagina,
      limite: 20
    });
    
    mostrarResultadosBusqueda(resultados);
  } catch (error) {
    console.error('Error de búsqueda:', error);
  }
};

🔧 Detalles Técnicos

Reglas de Codificación

Reglas básicas de codificación URL:

Caracteres Reservados:

  • :%3A
  • /%2F
  • ?%3F
  • #%23
  • [%5B
  • ]%5D
  • @%40

Caracteres No Reservados:

  • A-Z, a-z, 0-9 → Sin cambios
  • -, ., _, ~ → Sin cambios

Otros Caracteres:

  • Convertir a secuencia de bytes UTF-8, luego codificar cada byte en formato %XX

Implementación en JavaScript

// Funciones estándar de codificación/decodificación
const codificarURL = (str) => {
  return encodeURIComponent(str);
};

const decodificarURL = (str) => {
  try {
    return decodeURIComponent(str);
  } catch (error) {
    console.error('Error de decodificación:', error);
    return str; // Devolver cadena original si falla la decodificación
  }
};

// Función de codificación personalizada (control más fino)
const codificarURLPersonalizado = (str, codificarEspacioComoMas = false) => {
  let codificado = encodeURIComponent(str);
  
  if (codificarEspacioComoMas) {
    codificado = codificado.replace(/%20/g, '+');
  }
  
  return codificado;
};

// Función de decodificación segura
const decodificarURLSeguro = (str) => {
  try {
    // Convertir + a espacio (para datos de formulario)
    const normalizado = str.replace(/\+/g, ' ');
    return decodeURIComponent(normalizado);
  } catch (error) {
    console.error('Error de decodificación:', error);
    return str;
  }
};

💡 Consejos de Uso

  • Selección de Función Apropiada: Distinguir entre encodeURIComponent() y encodeURI()
  • Manejo de Errores: No olvidar el manejo de excepciones al decodificar
  • Codificación de Caracteres: Asumir codificación UTF-8
  • Pruebas: Probar exhaustivamente con datos que contengan caracteres especiales

⚠️ Notas Importantes

  • Doble Codificación: Evitar codificar nuevamente cadenas ya codificadas
  • Errores de Decodificación: Pueden ocurrir excepciones al decodificar cadenas de codificación inválidas
  • Limitaciones de Caracteres: Algunos sistemas pueden tener limitaciones en la longitud de URL
  • Seguridad: Realizar validación apropiada al incluir entrada de usuario en URLs

🚀 Cómo Usar

  1. Entrada de Texto: Ingrese el texto o URL a codificar/decodificar en el cuadro de entrada
  2. Selección de Operación: Haga clic en el botón "Codificar" o "Decodificar"
  3. Verificación de Resultados: Los resultados de conversión se muestran en el área de salida
  4. Uso de Copia: Use el botón "Copiar" para copiar los resultados al portapapeles
  5. Verificación de Errores: Se muestran mensajes de error para formatos inválidos

Consejo: Esta herramienta procesa localmente en el lado del cliente y no envía datos de entrada al servidor, garantizando la protección de la privacidad.