INFOTEP Técnico en Programación de Páginas Web study materials
INFOTEP Técnico en Programación de Páginas Web study resources

Panel de reservas para un tour operador en Samaná

INFOTEP Técnico en Programación de Páginas Web · Put your knowledge to work in context.

All case studies

Panel de reservas para un tour operador en Samaná

Un tour operador de Samaná vende excursiones a 1.200 visitantes diarios; el 65 % entra desde móvil con 3G o 4G. El sitio actual es HTML y PHP 8.1 sobre hosting compartido con Apache y MySQL: las páginas de excursiones se renderizan en el servidor y un calendario consulta la disponibilidad cada 30 segundos mediante AJAX. El tiempo hasta el primer byte (TTFB) es de 2,4 s y el calendario parpadea cada vez que llega la respuesta. El equipo propone reescribir todo como SPA con React alojada en Netlify y consumir una API PHP en el hosting actual. Hay tres semanas, un desarrollador junior y no se puede contratar VPS. Además, al probar el entorno de staging, la consola muestra un error de CORS al llamar a /api/disponibilidad, aunque la petición devuelve 200 en la pestaña Network. La gerencia exige conservar el posicionamiento de las páginas de excursiones y que el calendario funcione con cookies de sesión.

1. ¿Debe el equipo reescribir todo como SPA? Razona la decisión y describe la arquitectura cliente-servidor resultante.

Read the worked answer

No conviene reescribir todo como SPA en tres semanas. El sitio tiene dos necesidades distintas: páginas de excursiones que deben posicionar y cargar rápido, y un calendario interactivo. Una SPA traslada el renderizado al navegador: aumenta el JavaScript inicial, empeora el LCP y el TTFB percibido en 3G y obliga a resolver SEO con SSR o prerender, algo inviable con un junior y tres semanas. Además, la API en otro origen añade CORS y cookies cross-site, justo el error que ya aparece.

Arquitectura recomendada: renderizado en servidor + mejora progresiva. Mantener las páginas PHP como están, con HTML semántico y caché HTTP. El calendario se carga como componente JS independiente que llama a /api/disponibilidad en el mismo origen (o mediante proxy inverso), con fetch, estados de carga y fallback a un enlace de contacto si falla JS. Así el HTML inicial sigue siendo indexable y el calendario no bloquea el resto.

Flujo: navegador → Apache/PHP → MySQL; para disponibilidad, el cliente pide JSON, el servidor consulta con índices y responde con Cache-Control corto. Si más adelante se quiere SPA, se haría por secciones, no un big bang. La decisión se basa en riesgo, plazo, SEO y arquitectura, no en moda.

2. Explica la causa del error de CORS y la corrección concreta en el servidor, considerando que se usan cookies de sesión.

Read the worked answer

El 200 en Network no significa que el navegador entregue la respuesta: la same-origin policy bloquea la lectura si el origen que ejecuta JS (staging) no está autorizado por el servidor. El preflight OPTIONS probablemente no está contemplado o responde sin cabeceras.

Corrección en el servidor, no en el cliente:

  • Access-Control-Allow-Origin: https://staging.midominio.com (origen exacto; nunca * si hay credenciales).
  • Access-Control-Allow-Credentials: true.
  • Responder OPTIONS con Access-Control-Allow-Methods: GET, POST, OPTIONS y Access-Control-Allow-Headers: Content-Type.
  • Vary: Origin para que las cachés no mezclen respuestas.
  • En la cookie: Secure, HttpOnly, SameSite=None si el cruce es real; si se puede, servir la API bajo el mismo dominio y evitar CORS.

Un proxy inverso en el mismo origen elimina la clase de problema y simplifica cookies. No se debe arreglar con mode: 'no-cors': eso impide leer la respuesta.

3. Propón tres cambios para reducir el TTFB y el parpadeo del calendario sin cambiar de infraestructura.

Read the worked answer

Tres cambios: (1) cachear disponibilidad 15–30 s con Cache-Control: public, max-age=15, stale-while-revalidate=30 y ETag; (2) dejar de hacer polling cada 30 s: consultar al abrir el calendario, al cambiar de fecha y con document.visibilityState, y actualizar solo las celdas que cambian; (3) reducir trabajo en servidor: índice compuesto por fecha/estado, consulta que devuelva solo campos necesarios, OPcache y compresión Brotli/gzip.

Con 1.200 visitas/día y sondeos cada 30 s no hay 40 req/s constantes, pero en horas pico el polling genera carga y respuestas obsoletas. Medir TTFB antes y después con PerformanceObserver; si el TTFB sigue alto, separar la consulta lenta en una vista cacheada. El parpadeo se corrige también conservando el DOM y aplicando solo los cambios, no reemplazando todo el calendario.