Servicio de URLs cortas propio con Workers + KV: de cero a producción

¿Por qué monté mi propio servicio de URLs cortas?
Durante casi dos años usé un servicio de acortamiento de terceros. Una mañana, todos los enlaces dejaron de funcionar: el proveedor anunció el cierre de repente y cientos de enlaces compartidos en redes sociales devolvían 404.
En ese momento pensé: ¿y si tuviera un servicio totalmente mío? Datos bajo mi control, personalización a medida y sin depender de que un tercero desaparezca.
Cloudflare Workers + KV encaja perfectamente:
- Cuota gratuita muy generosa (100.000 solicitudes al día)
- Más de 200 nodos globales, acceso rapidísimo
- Despliegue sencillo, pocas líneas de código
- Datos bajo tu control, los guardas el tiempo que quieras
En este artículo comparto cómo monté mi servicio con Workers + KV: códigos personalizados, estadísticas de visitas y más. Incluyo todo el código; siguiendo los pasos, en media hora puedes tenerlo online.
¿Por qué Workers + KV?
¿Qué es Cloudflare Workers?
En pocas palabras, Workers son funciones serverless que corren en la red edge de Cloudflare. Escribes el código, se despliega en más de 200 nodos y el tráfico se enruta al más cercano, con latencia muy baja.
Lo importante: la cuota gratuita es muy generosa:
- 100.000 solicitudes al día
- 10 ms de CPU por solicitud
- Para uso personal o equipos pequeños, suele bastar
Ventajas del almacenamiento KV
KV (Key-Value) es la base de datos distribuida de Cloudflare, optimizada para edge computing:
- Lecturas muy rápidas: mediana de 12 ms, con datos en caché en nodos edge
- Sincronización global: tras escribir, en 60 segundos llega a todos los nodos
- Cuota gratuita: 100.000 lecturas y 1.000 escrituras al día
Para URLs cortas, KV encaja de maravilla:
- Código corto como clave, URL original como valor
- Escenario lectura intensiva (pocas creaciones, muchas visitas)
- Distribución global, acceso rápido desde cualquier lugar
Comparación con servicios de terceros
| Característica | Servicio de terceros | Propio con Workers + KV |
|---|---|---|
| Control de datos | Datos en manos del proveedor | Control total |
| Personalización | Funciones fijas | Lo que necesites |
| Estabilidad | Riesgo de cierre | Respaldo de Cloudflare |
| Publicidad | Posible página intermedia | Sin anuncios |
| Costo | Posible pago | Prácticamente gratis |
| Velocidad | Depende del proveedor | Red edge global |
Montar el servicio desde cero
Basta de teoría, vamos a la práctica.
Preparación
1. Registrar cuenta en Cloudflare
Ve a cloudflare.com y crea una cuenta; el plan gratuito basta.
2. Instalar Wrangler CLI
Wrangler es la herramienta oficial de línea de comandos de Cloudflare para gestionar proyectos Workers.
npm install -g wrangler
# o con yarn
yarn global add wrangler
Tras instalar, inicia sesión en tu cuenta:
wrangler login
Se abrirá el navegador para autorizar; acepta y listo.
3. Crear el proyecto
mkdir my-shortlink
cd my-shortlink
wrangler init
Sigue las indicaciones y elige un proyecto JavaScript (también puedes usar TypeScript).
Paso 1: crear el espacio de nombres KV
KV requiere un «namespace» (espacio de nombres), algo así como una tabla en una base de datos.
Ejecuta:
# Crear espacio KV de producción
wrangler kv namespace create SHORTLINKS
# Crear espacio KV de preview (pruebas locales)
wrangler kv namespace create SHORTLINKS --preview
El comando devuelve dos ID, algo como:
{ binding = "SHORTLINKS", id = "abc123..." }
{ binding = "SHORTLINKS", preview_id = "def456..." }
Importante: anota ambos ID, los necesitarás.
Luego edita wrangler.toml y añade la vinculación KV:
name = "my-shortlink"
main = "src/index.js"
compatibility_date = "2025-12-01"
# Vinculación del espacio de nombres KV
kv_namespaces = [
{ binding = "SHORTLINKS", id = "tu ID de producción", preview_id = "tu ID de preview" }
]
binding = "SHORTLINKS" significa que en el código accedes al almacenamiento con env.SHORTLINKS.
Paso 2: implementar la funcionalidad básica
Escribe el código principal. Abre src/index.js y pega lo siguiente:
export default {
async fetch(request, env) {
const url = new URL(request.url);
const path = url.pathname.slice(1); // quitar la / inicial
// Ruta raíz
if (path === '') {
return new Response('¡Bienvenido al servicio de URLs cortas!', { status: 200 });
}
// GET: redirección de URL corta
if (request.method === 'GET') {
// Consultar en KV la URL original del código corto
const targetUrl = await env.SHORTLINKS.get(path);
if (targetUrl) {
// Encontrada: redirección 301
return Response.redirect(targetUrl, 301);
} else {
// No encontrada: 404
return new Response('La URL corta no existe', { status: 404 });
}
}
// POST: crear URL corta
if (request.method === 'POST') {
try {
const body = await request.json();
const { url: targetUrl, code } = body;
// Validación básica
if (!targetUrl) {
return new Response('Falta el parámetro url', { status: 400 });
}
// Generar código corto
const shortCode = code || generateRandomCode();
// Comprobar si ya existe
const existing = await env.SHORTLINKS.get(shortCode);
if (existing) {
return new Response('El código corto ya existe', { status: 409 });
}
// Guardar en KV
await env.SHORTLINKS.put(shortCode, targetUrl);
// Devolver resultado
return new Response(JSON.stringify({
shortCode,
shortUrl: `${url.origin}/${shortCode}`,
targetUrl
}), {
status: 201,
headers: { 'Content-Type': 'application/json' }
});
} catch (error) {
return new Response('Formato de solicitud incorrecto', { status: 400 });
}
}
// Otros métodos no soportados
return new Response('Método no permitido', { status: 405 });
}
};
// Generar código aleatorio (6 caracteres alfanuméricos)
function generateRandomCode(length = 6) {
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
let code = '';
for (let i = 0; i < length; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length));
}
return code;
}
Explicación del código:
- Petición
GET: al visitartudominio.com/abc123, consulta en KV la URL deabc123y redirige con 301 - Petición
POST: recibeurly opcionalmentecode; si no haycode, genera uno aleatorio y lo guarda en KV generateRandomCode: genera una combinación aleatoria de 6 caracteres
Paso 3: pruebas locales
Tras escribir el código, prueba en local:
wrangler dev
Arranca un servidor local, normalmente en http://localhost:8787.
Probar creación de enlace:
curl -X POST http://localhost:8787 \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'
Respuesta:
{
"shortCode": "aBc123",
"shortUrl": "http://localhost:8787/aBc123",
"targetUrl": "https://example.com"
}
Probar acceso al enlace corto:
Abre http://localhost:8787/aBc123 en el navegador; debería redirigir a https://example.com.
Si todo va bien, la funcionalidad básica está lista.
Paso 4: soporte de códigos personalizados
El código anterior ya admite códigos personalizados: basta enviar el parámetro code en el POST:
curl -X POST http://localhost:8787 \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "code": "my-link"}'
Para mayor robustez, añade validación:
// En el manejo de POST, antes de generar el código corto
// Si el usuario envía un código personalizado, validar formato
if (code) {
// Solo letras, números y guiones
if (!/^[a-zA-Z0-9-]+$/.test(code)) {
return new Response('Formato de código corto incorrecto (solo letras, números y guiones)', { status: 400 });
}
// Límite de longitud
if (code.length < 3 || code.length > 20) {
return new Response('La longitud del código corto debe estar entre 3 y 20', { status: 400 });
}
}
Así evitas códigos raros con caracteres especiales o demasiado largos.
Paso 5: estadísticas de visitas
A menudo no solo quieres acortar enlaces, sino saber cuántas veces se visita cada uno.
Enfoque:
- En cada visita, además de redirigir, incrementa el contador
- Las estadísticas también van en KV, con clave
stats:{shortCode}
Modifica la parte GET:
// GET: redirección de URL corta
if (request.method === 'GET') {
const targetUrl = await env.SHORTLINKS.get(path);
if (targetUrl) {
// Actualizar estadísticas en segundo plano (sin bloquear la redirección)
const statsKey = `stats:${path}`;
// Actualización en background, sin afectar la velocidad
env.SHORTLINKS.get(statsKey).then(count => {
const newCount = (parseInt(count) || 0) + 1;
env.SHORTLINKS.put(statsKey, newCount.toString());
});
return Response.redirect(targetUrl, 301);
} else {
return new Response('La URL corta no existe', { status: 404 });
}
}
Añadir endpoint de consulta de estadísticas:
// Antes del manejo GET, añade esta comprobación
if (path.startsWith('stats/')) {
const shortCode = path.slice(6); // quitar el prefijo stats/
const statsKey = `stats:${shortCode}`;
const count = await env.SHORTLINKS.get(statsKey);
return new Response(JSON.stringify({
shortCode,
visits: parseInt(count) || 0
}), {
headers: { 'Content-Type': 'application/json' }
});
}
Ahora puedes consultar visitas en http://localhost:8787/stats/abc123.
Nota: KV no soporta operaciones atómicas; bajo alta concurrencia las estadísticas pueden ser imprecisas. Para precisión exacta, usa Durable Objects. Para la mayoría de usos personales, esta solución basta.
Paso 6: despliegue a producción
Tras las pruebas, despliega en la red global de Cloudflare:
wrangler deploy
Tras el despliegue, Wrangler te da una URL como https://my-shortlink.your-subdomain.workers.dev.
Esa es la dirección de tu servicio, con acceso global y buena velocidad.
Vincular dominio personalizado (opcional):
Si tienes un dominio (por ejemplo short.example.com), vincúlalo en Cloudflare Dashboard:
- Entra en Workers & Pages
- Selecciona tu Worker
- Settings > Triggers
- Añade Custom Domain
Así podrás usar tu dominio, por ejemplo https://short.example.com/abc123.
Funciones avanzadas
La base ya está; si quieres ir más allá, puedes añadir:
1. Creación por lotes
A veces necesitas crear varios enlaces de una vez:
// En el manejo de POST, añade lógica de lote
if (request.method === 'POST' && url.pathname === '/batch') {
try {
const body = await request.json();
const links = body.links; // formato: [{url, code?}, ...]
if (!Array.isArray(links)) {
return new Response('links debe ser un array', { status: 400 });
}
const results = [];
for (const link of links) {
const { url: targetUrl, code } = link;
const shortCode = code || generateRandomCode();
// Comprobar si ya existe
const existing = await env.SHORTLINKS.get(shortCode);
if (!existing) {
await env.SHORTLINKS.put(shortCode, targetUrl);
results.push({ shortCode, targetUrl, success: true });
} else {
results.push({ shortCode, targetUrl, success: false, error: 'El código corto ya existe' });
}
}
return new Response(JSON.stringify({ results }), {
headers: { 'Content-Type': 'application/json' }
});
} catch (error) {
return new Response('Formato de solicitud incorrecto', { status: 400 });
}
}
Uso:
curl -X POST http://localhost:8787/batch \
-H "Content-Type: application/json" \
-d '{
"links": [
{"url": "https://example1.com", "code": "link1"},
{"url": "https://example2.com"}
]
}'
2. Configurar expiración
KV admite TTL (Time To Live) para que los enlaces caduquen solos:
// Al guardar en KV, añade expirationTtl
await env.SHORTLINKS.put(shortCode, targetUrl, {
expirationTtl: 86400 // se borra tras 24 horas, en segundos
});
Para que el usuario defina la expiración:
const { url: targetUrl, code, ttl } = body;
const options = {};
if (ttl) {
options.expirationTtl = parseInt(ttl);
}
await env.SHORTLINKS.put(shortCode, targetUrl, options);
3. Control de acceso
Si no quieres que cualquiera cree enlaces, añade validación con API Token:
// En wrangler.toml añade variable de entorno
# [vars]
# API_TOKEN = "your-secret-token"
// Antes del manejo POST, valida
if (request.method === 'POST') {
const token = request.headers.get('Authorization');
if (token !== `Bearer ${env.API_TOKEN}`) {
return new Response('No autorizado', { status: 401 });
}
// ... lógica de creación
}
Incluye el token en la petición:
curl -X POST http://localhost:8787 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-secret-token" \
-d '{"url": "https://example.com"}'
4. Evitar abuso (rate limiting)
Para impedir la creación masiva de enlaces, limita la frecuencia:
// Usar la IP como identificador de límite
const clientIp = request.headers.get('CF-Connecting-IP');
const rateLimitKey = `ratelimit:${clientIp}`;
// Obtener contador actual
const count = await env.SHORTLINKS.get(rateLimitKey);
if (parseInt(count) >= 10) {
return new Response('Demasiadas solicitudes, inténtalo más tarde', { status: 429 });
}
// Incrementar contador, expira en 1 hora
const newCount = (parseInt(count) || 0) + 1;
await env.SHORTLINKS.put(rateLimitKey, newCount.toString(), {
expirationTtl: 3600 // 1 hora
});
Esto limita a 10 enlaces creados por IP y hora.
Optimización de rendimiento y buenas prácticas
Consejos de rendimiento
1. Estrategia de caché
Las lecturas de KV ya son rápidas (mediana 12 ms), pero puedes añadir caché en memoria del Worker:
// Map como caché en memoria sencilla
const cache = new Map();
const targetUrl = cache.get(path) || await env.SHORTLINKS.get(path);
if (targetUrl) {
cache.set(path, targetUrl);
return Response.redirect(targetUrl, 301);
}
Ojo: la memoria del Worker no es persistente; se pierde al reiniciar.
2. Reducir escrituras en KV
La cuota gratuita son 1.000 escrituras al día; si las estadísticas escriben demasiado, puedes superarla.
Opciones:
- Usar Durable Objects para estadísticas (operaciones atómicas)
- Escribir en KV solo cada N visitas
- Usar Cloudflare Analytics Engine
3. Configuración CORS
Si el frontend llamará al servicio, añade cabeceras CORS:
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
};
// Manejo de OPTIONS
if (request.method === 'OPTIONS') {
return new Response(null, { headers: corsHeaders });
}
// Añadir CORS en la respuesta
return new Response(body, {
headers: { ...headers, ...corsHeaders }
});
Control de costos
La cuota gratuita de Cloudflare Workers es generosa, pero conviene tenerla presente:
Cuota gratuita:
- 100.000 solicitudes al día
- KV: 100.000 lecturas y 1.000 escrituras al día
- 10 ms de CPU por solicitud
Costes al superar la cuota (plan Workers Paid, desde $5/mes):
- $0,50 por millón de solicitudes
- $0,50 por millón de lecturas KV
- $5,00 por millón de escrituras KV
- $0,50 por GB/mes de almacenamiento KV
Para uso personal, rara vez superas la cuota. Equipos pequeños con decenas de miles de visitas diarias también suelen estar cubiertos.
Ahorrar solicitudes:
- Redirección 301 (caché del navegador) en lugar de 302
- Recursos estáticos (panel de gestión) en Workers Pages, sin consumir solicitudes del Worker
- TTL adecuado para limpiar enlaces caducados
Consideraciones de seguridad
1. Evitar enlaces maliciosos
Si el servicio es público, alguien puede acortar sitios maliciosos.
Recomendaciones:
- Validación con API Token
- Lista negra de dominios conocidos
- Registrar IP del creador para trazabilidad
2. Evitar colisiones de códigos
Aunque 6 caracteres alfanuméricos dan 62^6 ≈ 56.800 millones de posibilidades y la colisión es improbable, hay que comprobar:
// Al crear enlace, comprobar si ya existe
const existing = await env.SHORTLINKS.get(shortCode);
if (existing) {
return new Response('El código corto ya existe', { status: 409 });
}
3. Restringir URL de destino
Puedes usar una lista blanca de dominios permitidos:
const allowedDomains = ['example.com', 'mywebsite.com'];
const targetDomain = new URL(targetUrl).hostname;
if (!allowedDomains.some(d => targetDomain.endsWith(d))) {
return new Response('Dominio de destino no permitido', { status: 403 });
}
Mi experiencia real de uso
Llevo varios meses usándolo. Esto es lo que he visto:
Ventajas:
- Muy rápido: latencia global suele estar por debajo de 50 ms, mucho mejor que el servicio de terceros anterior
- Estable: la red de Cloudflare es muy fiable, casi sin caídas
- Tranquilo: tras desplegar no hay que gestionar nada, escala sola ante picos de tráfico
- Gratis: unos miles de solicitudes diarias, dentro de la cuota gratuita
Pequeños inconvenientes:
- Retraso en escrituras KV: consistencia eventual; puede tardar decenas de segundos en sincronizarse globalmente. En URLs cortas suele importar poco, porque tras crear un enlace no suele visitarse al instante
- Estadísticas imprecisas: KV no tiene operaciones atómicas; bajo alta concurrencia hay error. Para precisión exacta, Durable Objects; fuera de la cuota gratuita cuesta más
Próximos pasos:
- Dashboard sencillo con Workers Pages para gestionar enlaces
- Cloudflare Analytics para datos detallados (origen, región, etc.)
- Generación de códigos QR para compartir offline
Resumen
Montar un servicio de URLs cortas con Cloudflare Workers + KV es rápido y económico. El código principal tiene menos de 100 líneas, el despliegue es un solo comando y los datos quedan en tus manos, sin depender de terceros.
Si tienes una necesidad similar, te animo a probarlo. Todo el código está aquí; cópialo y en media hora puedes tenerlo online.
Pasos clave:
- Registrar cuenta en Cloudflare e instalar Wrangler
- Crear espacio KV y configurar wrangler.toml
- Escribir código para GET (redirección) y POST (crear enlace)
- Probar en local y desplegar a producción
Luego puedes ir añadiendo estadísticas, lotes, expiración y más. El código es tuyo: lo modificas como quieras.
¿Dudas? Déjalas en los comentarios. ¡Que disfrutes montando tu propio servicio de URLs cortas!
Flujo completo para montar un servicio de URLs cortas con Cloudflare Workers + KV
Monta un servicio de acortamiento desde cero con creación de enlaces, redirección y estadísticas de visitas; online en media hora
⏱️ Estimated time: 30 min
- 1
Step 1: Preparación: registrar cuenta de Cloudflare e instalar Wrangler CLI
Paso 1: registrar cuenta en Cloudflare
• Ve a cloudflare.com y crea una cuenta; el plan gratuito basta
Paso 2: instalar Wrangler CLI
• Wrangler es la herramienta oficial de línea de comandos de Cloudflare para gestionar proyectos Workers
• Ejecuta: npm install -g wrangler
• O bien: yarn global add wrangler
• Tras instalar, inicia sesión: wrangler login
• Se abrirá el navegador para autorizar; acepta y listo
Paso 3: crear el proyecto
• mkdir my-shortlink
• cd my-shortlink
• wrangler init
• Sigue las indicaciones y elige un proyecto JavaScript (también puedes usar TypeScript) - 2
Step 2: Crear el espacio de nombres KV y configurar wrangler.toml
Crear el espacio de nombres KV:
Método 1: en Cloudflare Dashboard
• Entra en Workers & Pages → KV
• Haz clic en Create a namespace
• Pon un nombre (por ejemplo SHORTLINKS) y créalo
Método 2: línea de comandos
• wrangler kv:namespace create SHORTLINKS
Configurar wrangler.toml:
Abre wrangler.toml y añade al final la vinculación KV:
[[kv_namespaces]]
binding = "SHORTLINKS"
id = "tu ID de espacio de nombres"
Así podrás acceder a KV desde el código con env.SHORTLINKS - 3
Step 3: Código principal: crear URLs cortas y redireccionar
Funcionalidad principal:
1. Generar código corto:
• Soporta códigos personalizados y generación aleatoria
• Puedes usar combinaciones de 6 caracteres alfanuméricos
• Con 62^6≈56.800 millones de posibilidades, la probabilidad de colisión es muy baja
2. Guardar en KV:
• El código corto es la clave, la URL original el valor
• También puedes guardar metadatos (fecha de creación, visitas, etc.)
3. Redirección:
• En peticiones GET, lee la URL original desde KV
• Devuelve redirección 302 a la URL original
4. Estadísticas de visitas:
• Registra número de visitas y hora
• Puedes guardarlo en metadatos de KV
Ejemplo de código:
• GET (redirección): obtén el código corto de la ruta, lee la URL en KV, si existe devuelve 302, si no 404
• POST (crear enlace): recibe URL original y código opcional, genera código, comprueba colisiones, guarda en KV y devuelve la URL corta - 4
Step 4: Pruebas locales y despliegue a producción
Pruebas locales:
1. Ejecuta wrangler dev para el servidor local
2. Prueba crear enlaces y la redirección
Puedes usar curl:
• Crear enlace:
curl -X POST http://localhost:8787/create -H "Content-Type: application/json" -d '{"url":"https://example.com"}'
• Visitar enlace corto:
curl -L http://localhost:8787/abc123
(redirige a la URL original)
Despliegue a producción:
• Ejecuta: wrangler deploy
• Wrangler despliega el Worker en Cloudflare
• Tras el despliegue verás una URL del tipo:
your-worker-name.your-subdomain.workers.dev
• ¡Tu servicio de URLs cortas ya está online! - 5
Step 5: Funciones avanzadas y consideraciones de seguridad
Funciones avanzadas: 1) Estadísticas (registra visitas y hora en metadatos KV, actualiza el contador en cada acceso); 2) Expiración (TTL para que el enlace deje de funcionar); 3) Creación por lotes; 4) Panel de gestión (un dashboard sencillo con Workers Pages). Seguridad: 1) Evitar enlaces maliciosos (validación con API Token, lista negra de dominios, registrar IP del creador); 2) Evitar colisiones de códigos (comprobar si ya existe al crear); 3) Restringir URL de destino (lista blanca de dominios permitidos). Ahorrar solicitudes: usa redirección 301 (el navegador la cachea) en lugar de 302, sirve recursos estáticos con Workers Pages y configura TTL para limpiar enlaces caducados.
FAQ
¿Por qué montar un servicio de URLs cortas propio? ¿Qué ventajas tiene Workers + KV?
Ventajas de Workers + KV:
• Cuota gratuita muy generosa (100.000 solicitudes/día)
• Más de 200 nodos globales, acceso muy rápido
• Despliegue sencillo, pocas líneas de código
• Datos bajo tu control, los guardas el tiempo que quieras
Comparado con servicios de terceros:
• Control de datos (terceros vs. control total)
• Personalización (funciones fijas vs. lo que necesites)
• Estabilidad (riesgo de cierre vs. respaldo de Cloudflare)
• Publicidad (páginas intermedias vs. sin anuncios)
• Costo (posible pago vs. prácticamente gratis)
• Velocidad (depende del proveedor vs. red edge global)
¿Qué ventajas tiene KV? ¿Por qué encaja con un servicio de URLs cortas?
Ventajas de KV:
• Lecturas muy rápidas, mediana de 12 ms (datos en caché en nodos edge)
• Sincronización global: tras escribir, en 60 segundos llega a todos los nodos
• Cuota gratuita: 100.000 lecturas y 1.000 escrituras al día
Para URLs cortas, KV encaja de maravilla:
• Código corto como clave, URL original como valor
• Escenario lectura intensiva (pocas creaciones, muchas visitas)
• Distribución global, acceso rápido desde cualquier lugar
Cuota gratuita:
• Workers: 100.000 solicitudes/día
• KV: 100.000 lecturas y 1.000 escrituras/día
• Para uso personal suele bastar; equipos pequeños con decenas de miles de visitas diarias también
Costes al superar la cuota (plan Workers Paid desde $5/mes):
• $0,50 por millón de solicitudes
• $0,50 por millón de lecturas KV
• $5,00 por millón de escrituras KV
• $0,50 por GB/mes de almacenamiento KV
¿Cómo montar un servicio de URLs cortas desde cero? ¿Cuáles son los pasos?
Paso 1: registrar cuenta en Cloudflare (cloudflare.com, plan gratuito)
Paso 2: instalar Wrangler CLI (npm install -g wrangler, luego wrangler login)
Paso 3: crear proyecto (mkdir my-shortlink, cd my-shortlink, wrangler init)
Crear espacio KV y configurar:
• En Dashboard: Workers & Pages → KV → Create a namespace (ej. SHORTLINKS)
• O en CLI: wrangler kv:namespace create SHORTLINKS
Configurar wrangler.toml:
• Añade la vinculación KV al final del archivo
• Accede desde el código con env.SHORTLINKS
Código principal:
GET (redirección):
• Obtén el código corto de la ruta
• Lee la URL original en KV
• Si existe, redirección 302; si no, 404
POST (crear enlace):
• Recibe URL original y código opcional
• Genera código (aleatorio si no hay personalizado)
• Comprueba si ya existe
• Guarda en KV y devuelve la URL corta
Pruebas y despliegue:
• wrangler dev para probar localmente
• wrangler deploy para producción
¿Cómo se implementan las funciones principales del servicio?
1) Generar código corto:
• Códigos personalizados o aleatorios
• 6 caracteres alfanuméricos, 62^6≈56.800 millones de posibilidades, baja probabilidad de colisión
2) Guardar en KV:
• Código corto = clave, URL original = valor
• Metadatos opcionales: fecha de creación, visitas, etc.
3) Redirección:
• En GET, lee URL original desde KV
• Devuelve redirección 302
4) Estadísticas:
• Registra visitas y hora
• En metadatos KV, actualiza contador en cada acceso
Ejemplo de código:
GET (redirección):
• Código corto desde la ruta
• Lee URL en KV
• 302 si existe, 404 si no
POST (crear):
• URL original y código opcional
• Genera código, comprueba colisión
• Guarda en KV y devuelve URL corta
Funciones avanzadas:
• Estadísticas de visitas
• Expiración con TTL
• Creación por lotes
• Panel con Workers Pages
¿Qué consideraciones de seguridad hay al usar un servicio de URLs cortas?
1) Evitar enlaces maliciosos:
• Si el servicio es público, alguien puede acortar sitios maliciosos
• Recomendaciones:
- Validación con API Token
- Lista negra de dominios conocidos
- Registrar IP del creador para trazabilidad
2) Evitar colisiones de códigos:
• Aunque 62^6≈56.800 millones de posibilidades hacen la colisión improbable, hay que comprobar:
const existing = await env.SHORTLINKS.get(shortCode);
if (existing) {
return new Response('El código corto ya existe', { status: 409 });
}
3) Restringir URL de destino:
• Lista blanca de dominios permitidos:
const allowedDomains = ['example.com', 'mywebsite.com'];
const targetDomain = new URL(targetUrl).hostname;
if (!allowedDomains.some(d => targetDomain.endsWith(d))) {
return new Response('Dominio de destino no permitido', { status: 403 });
}
Ahorrar solicitudes:
• Redirección 301 (caché del navegador) en lugar de 302
• Recursos estáticos en Workers Pages sin consumir solicitudes del Worker
• TTL adecuado para limpiar enlaces caducados
¿Cómo es la experiencia real de uso? ¿Ventajas y desventajas?
Ventajas:
• Muy rápido (latencia global suele estar por debajo de 50 ms, mucho mejor que servicios de terceros)
• Estable (la red de Cloudflare es muy fiable, casi sin caídas)
• Tranquilo (tras desplegar no hay que gestionar nada, escala sola)
• Gratis (con unos miles de solicitudes diarias, dentro de la cuota gratuita)
Pequeños inconvenientes:
• Retraso en escrituras KV (consistencia eventual; puede tardar decenas de segundos en sincronizarse globalmente; en URLs cortas suele importar poco)
• Estadísticas imprecisas (KV no tiene operaciones atómicas; bajo alta concurrencia hay error; para precisión usa Durable Objects, más caro fuera de la cuota)
Próximos pasos:
• Dashboard sencillo con Workers Pages
• Cloudflare Analytics para datos detallados (origen, región, etc.)
• Generación de códigos QR para compartir offline
12 min de lectura · Publicado el: 1 dic 2025 · Actualizado el: 21 ago 2026
Cloudflare Full Stack
Si llegaste desde búsqueda, lo más rápido es ir al artículo anterior o siguiente de esta misma serie.
Anterior
¿Cuotas de tráfico S3 de miles al mes? Migra a R2 en 3 pasos y ahorra un 90% (casos reales)
¿Las cuotas de tráfico de S3 disparan tu factura? Te guiamos paso a paso para migrar a Cloudflare R2 con cero cuota de egreso y ahorrar más de $10,896 al año. Incluye comparativa de 3 métodos de migración, pruebas de compatibilidad API y tutorial de 30 minutos con cálculo de costes reales.
Parte 14 de 23
Siguiente
¿API Key expuesta en el frontend y con riesgo de abuso? Proxy con Workers en 5 minutos: protege tus claves con 100.000 solicitudes gratis al día
¿Llamar APIs directamente desde el frontend expone tus claves al robo y al abuso? Te enseñamos a montar un proxy API gratuito con Cloudflare Workers: despliegue en 5 minutos, API Key segura en variables de entorno del servidor, 100.000 solicitudes gratis al día y sin problemas de CORS.
Parte 16 de 23



Comentarios
Inicia sesión con GitHub para dejar un comentario