Node
Tutorial Node: Módulo url
Aprende a usar el módulo URL de Node.js para parsing de URLs y manipulación de parámetros con URLSearchParams en aplicaciones web.
Aprende Node y certifícateParsing de URLs
El parsing de URLs es una operación fundamental en el desarrollo de aplicaciones web con Node.js. Cuando trabajamos con servidores HTTP, necesitamos extraer y analizar los diferentes componentes de las URLs que recibimos en las peticiones para poder procesarlas correctamente.
Node.js proporciona el módulo url
integrado que nos permite descomponer URLs complejas en sus partes constituyentes de manera sencilla y eficiente. Este módulo es especialmente útil cuando necesitamos acceder a elementos específicos como el protocolo, el host, la ruta, los parámetros de consulta o el fragmento.
Importación y uso básico
Para utilizar el módulo url
, simplemente lo importamos usando la sintaxis estándar de Node.js:
import { URL } from 'url';
La clase URL
es el constructor principal que utilizaremos para crear objetos URL y acceder a sus propiedades. Veamos un ejemplo básico:
import { URL } from 'url';
const miUrl = new URL('https://api.ejemplo.com/usuarios?activo=true&limite=10#seccion1');
console.log(miUrl.protocol); // 'https:'
console.log(miUrl.hostname); // 'api.ejemplo.com'
console.log(miUrl.pathname); // '/usuarios'
console.log(miUrl.search); // '?activo=true&limite=10'
console.log(miUrl.hash); // '#seccion1'
Propiedades principales del objeto URL
El objeto URL nos proporciona acceso directo a todas las partes componentes de una URL a través de propiedades específicas:
protocol
: El esquema de la URL (http:, https:, ftp:, etc.)hostname
: El nombre del host sin el puertohost
: El nombre del host incluyendo el puerto si está presenteport
: El número de puerto como stringpathname
: La ruta del recursosearch
: La cadena de consulta completa incluyendo el signo de interrogaciónhash
: El fragmento de la URL incluyendo el símbolo #
import { URL } from 'url';
const urlCompleta = new URL('https://tienda.com:8080/productos/electronicos?categoria=moviles&precio=500#reviews');
console.log('Protocolo:', urlCompleta.protocol); // 'https:'
console.log('Host completo:', urlCompleta.host); // 'tienda.com:8080'
console.log('Solo hostname:', urlCompleta.hostname); // 'tienda.com'
console.log('Puerto:', urlCompleta.port); // '8080'
console.log('Ruta:', urlCompleta.pathname); // '/productos/electronicos'
console.log('Consulta:', urlCompleta.search); // '?categoria=moviles&precio=500'
console.log('Fragmento:', urlCompleta.hash); // '#reviews'
Parsing en aplicaciones HTTP
En el contexto de un servidor HTTP, el parsing de URLs es especialmente útil para analizar las peticiones entrantes. Podemos combinar el módulo url
con el módulo http
para extraer información de las URLs de las peticiones:
import http from 'http';
import { URL } from 'url';
const servidor = http.createServer((peticion, respuesta) => {
// Construimos la URL completa usando la URL base del servidor
const urlCompleta = new URL(peticion.url, `http://${peticion.headers.host}`);
console.log('Ruta solicitada:', urlCompleta.pathname);
console.log('Parámetros de consulta:', urlCompleta.search);
// Lógica de enrutamiento basada en la ruta
if (urlCompleta.pathname === '/usuarios') {
respuesta.writeHead(200, { 'Content-Type': 'application/json' });
respuesta.end(JSON.stringify({ mensaje: 'Lista de usuarios' }));
} else if (urlCompleta.pathname === '/productos') {
respuesta.writeHead(200, { 'Content-Type': 'application/json' });
respuesta.end(JSON.stringify({ mensaje: 'Lista de productos' }));
} else {
respuesta.writeHead(404, { 'Content-Type': 'text/plain' });
respuesta.end('Recurso no encontrado');
}
});
servidor.listen(3000, () => {
console.log('Servidor ejecutándose en puerto 3000');
});
Manejo de URLs relativas
El constructor URL
también puede manejar URLs relativas cuando proporcionamos una URL base como segundo parámetro. Esto es útil cuando trabajamos con rutas relativas en nuestras aplicaciones:
import { URL } from 'url';
const urlBase = 'https://api.miapp.com/v1/';
// URLs relativas se resuelven contra la base
const url1 = new URL('usuarios', urlBase);
const url2 = new URL('../admin/configuracion', urlBase);
const url3 = new URL('/publico/imagenes/logo.png', urlBase);
console.log(url1.href); // 'https://api.miapp.com/v1/usuarios'
console.log(url2.href); // 'https://api.miapp.com/admin/configuracion'
console.log(url3.href); // 'https://api.miapp.com/publico/imagenes/logo.png'
Validación de URLs
Una ventaja importante del constructor URL
es que valida automáticamente la sintaxis de las URLs. Si intentamos crear un objeto URL con una cadena malformada, se lanzará una excepción:
import { URL } from 'url';
try {
const urlValida = new URL('https://ejemplo.com/ruta');
console.log('URL válida:', urlValida.href);
} catch (error) {
console.error('URL inválida:', error.message);
}
try {
const urlInvalida = new URL('esto-no-es-una-url-valida');
console.log('Esta línea no se ejecutará');
} catch (error) {
console.error('Error capturado:', error.message);
// Error capturado: Invalid URL: esto-no-es-una-url-valida
}
Esta validación automática nos ayuda a detectar problemas en las URLs antes de procesarlas, evitando errores inesperados en nuestra aplicación.
Modificación de componentes URL
Los objetos URL son mutables, lo que significa que podemos modificar sus propiedades después de la creación. Esto es útil para construir URLs dinámicamente:
import { URL } from 'url';
const miUrl = new URL('https://api.ejemplo.com/usuarios');
// Modificamos diferentes componentes
miUrl.pathname = '/productos';
miUrl.search = '?categoria=electronica&disponible=true';
miUrl.hash = '#resultados';
console.log(miUrl.href);
// 'https://api.ejemplo.com/productos?categoria=electronica&disponible=true#resultados'
// También podemos cambiar el protocolo y el host
miUrl.protocol = 'http:';
miUrl.hostname = 'localhost';
miUrl.port = '3000';
console.log(miUrl.href);
// 'http://localhost:3000/productos?categoria=electronica&disponible=true#resultados'
URLSearchParams
Los parámetros de consulta en las URLs son elementos clave para transmitir información entre el cliente y el servidor. Node.js proporciona la clase URLSearchParams
que nos permite manipular estos parámetros de forma intuitiva y eficiente, sin necesidad de realizar parsing manual de cadenas.
La clase URLSearchParams
está diseñada específicamente para trabajar con la parte de consulta de las URLs (la sección que aparece después del signo ?
). Esta herramienta nos permite agregar, modificar, eliminar y iterar sobre parámetros de consulta de manera programática.
Creación y uso básico
Podemos crear una instancia de URLSearchParams
de varias formas diferentes:
import { URLSearchParams } from 'url';
// Desde una cadena de consulta
const params1 = new URLSearchParams('nombre=Juan&edad=25&activo=true');
// Desde un objeto
const params2 = new URLSearchParams({
producto: 'laptop',
marca: 'Dell',
precio: '899'
});
// Vacío para construir dinámicamente
const params3 = new URLSearchParams();
Métodos principales para manipular parámetros
La clase URLSearchParams
ofrece métodos intuitivos para gestionar parámetros de consulta:
Agregar parámetros:
import { URLSearchParams } from 'url';
const parametros = new URLSearchParams();
parametros.append('categoria', 'electronica');
parametros.append('disponible', 'true');
parametros.append('precio_min', '100');
parametros.append('precio_max', '500');
console.log(parametros.toString());
// 'categoria=electronica&disponible=true&precio_min=100&precio_max=500'
Obtener valores:
import { URLSearchParams } from 'url';
const consulta = new URLSearchParams('usuario=admin&rol=editor&activo=true&rol=viewer');
// Obtener un valor específico
console.log(consulta.get('usuario')); // 'admin'
console.log(consulta.get('activo')); // 'true'
// Obtener todos los valores de un parámetro (útil para parámetros repetidos)
console.log(consulta.getAll('rol')); // ['editor', 'viewer']
// Verificar si existe un parámetro
console.log(consulta.has('usuario')); // true
console.log(consulta.has('email')); // false
Modificar y eliminar parámetros:
import { URLSearchParams } from 'url';
const filtros = new URLSearchParams('categoria=ropa&talla=M&color=azul&descuento=10');
// Modificar un valor existente
filtros.set('descuento', '20');
filtros.set('categoria', 'zapatos');
// Eliminar parámetros
filtros.delete('color');
console.log(filtros.toString());
// 'categoria=zapatos&talla=M&descuento=20'
Integración con objetos URL
La combinación de URL
y URLSearchParams
nos proporciona un control completo sobre las URLs y sus parámetros de consulta:
import { URL } from 'url';
const miUrl = new URL('https://tienda.com/buscar?q=telefono');
// Acceder a los parámetros existentes
console.log(miUrl.searchParams.get('q')); // 'telefono'
// Agregar nuevos parámetros
miUrl.searchParams.append('marca', 'Samsung');
miUrl.searchParams.append('precio_max', '800');
miUrl.searchParams.set('ordenar', 'precio_asc');
console.log(miUrl.href);
// 'https://tienda.com/buscar?q=telefono&marca=Samsung&precio_max=800&ordenar=precio_asc'
// Limpiar todos los parámetros
miUrl.searchParams.delete('q');
miUrl.searchParams.delete('marca');
console.log(miUrl.href);
// 'https://tienda.com/buscar?precio_max=800&ordenar=precio_asc'
Procesamiento de parámetros en servidores HTTP
En aplicaciones web reales, frecuentemente necesitamos extraer y procesar los parámetros de consulta de las peticiones HTTP entrantes:
import http from 'http';
import { URL } from 'url';
const servidor = http.createServer((peticion, respuesta) => {
const urlCompleta = new URL(peticion.url, `http://${peticion.headers.host}`);
const parametros = urlCompleta.searchParams;
if (urlCompleta.pathname === '/productos') {
// Extraer parámetros de filtrado
const categoria = parametros.get('categoria') || 'todas';
const limite = parseInt(parametros.get('limite')) || 10;
const ordenar = parametros.get('ordenar') || 'nombre';
// Simular respuesta basada en parámetros
const respuestaData = {
categoria: categoria,
limite: limite,
ordenamiento: ordenar,
total: 150,
mensaje: `Mostrando ${limite} productos de la categoría '${categoria}'`
};
respuesta.writeHead(200, { 'Content-Type': 'application/json' });
respuesta.end(JSON.stringify(respuestaData, null, 2));
} else if (urlCompleta.pathname === '/buscar') {
const termino = parametros.get('q');
if (!termino) {
respuesta.writeHead(400, { 'Content-Type': 'application/json' });
respuesta.end(JSON.stringify({ error: 'Parámetro de búsqueda requerido' }));
return;
}
respuesta.writeHead(200, { 'Content-Type': 'application/json' });
respuesta.end(JSON.stringify({
busqueda: termino,
resultados: `Resultados para: ${termino}`
}));
}
});
servidor.listen(3000, () => {
console.log('Servidor ejecutándose en puerto 3000');
console.log('Prueba: http://localhost:3000/productos?categoria=electronica&limite=5&ordenar=precio');
console.log('Prueba: http://localhost:3000/buscar?q=laptop');
});
Iteración sobre parámetros
URLSearchParams
implementa el protocolo de iteración de JavaScript, lo que nos permite recorrer todos los parámetros de diferentes maneras:
import { URLSearchParams } from 'url';
const parametros = new URLSearchParams('nombre=Ana&edad=30&ciudad=Madrid&hobby=lectura&hobby=natacion');
// Iterar sobre todas las entradas clave-valor
console.log('=== Todas las entradas ===');
for (const [clave, valor] of parametros) {
console.log(`${clave}: ${valor}`);
}
// Iterar solo sobre las claves
console.log('\n=== Solo claves ===');
for (const clave of parametros.keys()) {
console.log(clave);
}
// Iterar solo sobre los valores
console.log('\n=== Solo valores ===');
for (const valor of parametros.values()) {
console.log(valor);
}
// Usar forEach
console.log('\n=== Usando forEach ===');
parametros.forEach((valor, clave) => {
console.log(`Parámetro ${clave} tiene el valor: ${valor}`);
});
Manejo de parámetros con valores múltiples
Algunos parámetros pueden aparecer múltiples veces en una URL. URLSearchParams
maneja esta situación de forma elegante:
import { URLSearchParams } from 'url';
const filtros = new URLSearchParams();
// Agregar múltiples valores para el mismo parámetro
filtros.append('color', 'rojo');
filtros.append('color', 'azul');
filtros.append('color', 'verde');
filtros.append('talla', 'M');
filtros.append('talla', 'L');
console.log('Cadena completa:', filtros.toString());
// 'color=rojo&color=azul&color=verde&talla=M&talla=L'
// Obtener el primer valor
console.log('Primer color:', filtros.get('color')); // 'rojo'
// Obtener todos los valores
console.log('Todos los colores:', filtros.getAll('color')); // ['rojo', 'azul', 'verde']
console.log('Todas las tallas:', filtros.getAll('talla')); // ['M', 'L']
// Reemplazar todos los valores con set()
filtros.set('color', 'negro'); // Elimina todos los colores anteriores
console.log('Después de set:', filtros.getAll('color')); // ['negro']
Construcción dinámica de URLs con parámetros
Una aplicación práctica común es construir URLs dinámicamente basándose en condiciones o datos del usuario:
import { URL } from 'url';
function construirUrlBusqueda(baseUrl, criterios) {
const url = new URL(baseUrl);
// Agregar parámetros solo si tienen valor
if (criterios.termino) {
url.searchParams.set('q', criterios.termino);
}
if (criterios.categoria && criterios.categoria !== 'todas') {
url.searchParams.set('categoria', criterios.categoria);
}
if (criterios.precioMin) {
url.searchParams.set('precio_min', criterios.precioMin.toString());
}
if (criterios.precioMax) {
url.searchParams.set('precio_max', criterios.precioMax.toString());
}
if (criterios.etiquetas && criterios.etiquetas.length > 0) {
criterios.etiquetas.forEach(etiqueta => {
url.searchParams.append('etiqueta', etiqueta);
});
}
return url.href;
}
// Ejemplo de uso
const criteriosBusqueda = {
termino: 'laptop gaming',
categoria: 'electronica',
precioMin: 500,
precioMax: 1500,
etiquetas: ['alta-gama', 'portatil', 'gaming']
};
const urlFinal = construirUrlBusqueda('https://tienda.com/buscar', criteriosBusqueda);
console.log(urlFinal);
// 'https://tienda.com/buscar?q=laptop+gaming&categoria=electronica&precio_min=500&precio_max=1500&etiqueta=alta-gama&etiqueta=portatil&etiqueta=gaming'
Otras lecciones de Node
Accede a todas las lecciones de Node y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Instalación De Node.js
Introducción Y Entorno
Fundamentos Del Entorno Node.js
Introducción Y Entorno
Estructura De Proyecto Y Package.json
Introducción Y Entorno
Introducción A Node
Introducción Y Entorno
Gestor De Versiones Nvm
Introducción Y Entorno
Repl De Nodejs
Introducción Y Entorno
Ejercicios de programación de Node
Evalúa tus conocimientos de esta lección Módulo url con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.