La arquitectura de una web
Qué parte de una aplicación web se ejecuta en el navegador y qué parte en el servidor, cómo está hecho un navegador por dentro, por qué la seguridad no puede vivir en el cliente y qué herramientas rodean hoy al desarrollo de front-end.
Qué se ejecuta en el navegador y qué en el servidor
Una aplicación web está partida en dos mitades que corren en máquinas distintas. La mitad de cliente, o front-end, viaja por la red y se ejecuta dentro del navegador del opositor: es el HTML que describe el contenido, el CSS que lo presenta y el JavaScript que lo hace reaccionar. La mitad de servidor, o back-end, se ejecuta en una máquina que el usuario no controla: recibe peticiones, consulta la base de datos, decide qué puede ver cada usuario y devuelve una respuesta.
Entre las dos mitades solo circula HTTP. El navegador manda una petición con un método (GET para pedir, POST para enviar datos) y una dirección; el servidor devuelve una respuesta con un código de estado y un cuerpo, que puede ser una página HTML, una hoja de estilo, una imagen o un fragmento de JSON. Nada más pasa de un lado a otro: el servidor no ve las variables de JavaScript del navegador y el navegador no ve el código del servidor.
| Cliente (navegador) | Servidor | |
|---|---|---|
| Qué se ejecuta | HTML, CSS y JavaScript | PHP, Python, Ruby, Java, Node.js |
| Quién lo controla | El usuario: puede leerlo, cambiarlo y saltárselo | La organización que publica la aplicación |
| Qué ve el usuario | Todo el código fuente que le llega | Solo la respuesta, nunca el código |
| Para qué sirve | Interfaz, validación cómoda, interacción sin recargar | Reglas de negocio, persistencia, autorización |
| Dónde están los datos | De paso, en memoria de la pestaña | En la base de datos y en el sistema de ficheros |
Todo lo que se ejecuta en el cliente es público y modificable por el usuario. Todo lo que decide algo importante tiene que ejecutarse en el servidor.
Para el examen
Todo lo del cliente: es público y modificable por el usuario
Qué va en el servidor: todo lo que decide algo importante
El cliente no es de fiar: dónde vive la seguridad
El navegador ejecuta código que el usuario puede leer entero, modificar con las herramientas de desarrollo o directamente saltarse enviando la petición HTTP a mano. Por eso la validación que se hace en el cliente sirve para dar una respuesta inmediata y ahorrar viajes al servidor, pero no protege de nada: es comodidad, no seguridad.
La regla práctica es que toda comprobación que importe se repite en el servidor. Si un formulario de matrícula limita el campo de un curso a los cursos publicados, el servidor tiene que volver a comprobar que ese curso existe y que ese alumno puede matricularse, aunque el formulario ya lo hubiera comprobado en el navegador.
- Validación de cliente: mejora la experiencia y filtra errores tontos. Se puede desactivar.
- Validación de servidor: es la única que decide. Nunca es opcional.
- Autorización: siempre en el servidor. Ocultar un botón en el HTML no impide llamar a la operación.
- Secretos: nunca en el cliente. Una clave escrita en JavaScript es una clave publicada.
Dos mecanismos del propio navegador acotan el daño. La política del mismo origen impide que el JavaScript de una página lea datos de otro origen distinto (otro esquema, dominio o puerto), que es lo que evita que una web cualquiera lea el correo abierto en otra pestaña. Y el XSS es el ataque que consiste en colar código JavaScript ajeno dentro de una página de confianza: se evita escapando todo lo que venga del usuario antes de pintarlo.
Si el examen pregunta dónde se valida, la respuesta es en los dos sitios, pero la que cuenta es la del servidor.
Para el examen
Dónde se valida: en los dos sitios
Cuál cuenta: la validación del servidor
El tipo MIME y el antecedente CGI
El tipo MIME es la etiqueta con la que el servidor le dice al navegador qué clase de contenido le está mandando. Se escribe como tipo barra subtipo, y el navegador la usa para decidir si pinta la respuesta, si la interpreta como código o si la descarga. Sin ella el navegador tendría que adivinar por la extensión del fichero, que es exactamente lo que se quiso evitar.
| Tipo MIME | Qué identifica |
|---|---|
| text/html | Una página HTML |
| text/css | Una hoja de estilo |
| text/xml o application/xml | Un documento XML |
| application/json | Datos en JSON |
| application/xhtml+xml | XHTML, es decir HTML escrito con reglas de XML |
| image/svg+xml | Un gráfico vectorial SVG |
| application/pdf | Un documento PDF |
CGI, de Common Gateway Interface, fue la primera forma de generar páginas dinámicas. El servidor web lanzaba un programa externo, escrito en cualquier lenguaje, le pasaba los datos de la petición en variables de entorno y devolvía al navegador lo que ese programa imprimiera. Era lento, porque arrancaba un proceso nuevo por cada petición, pero es la antesala directa de todo lo que vino después: los módulos incrustados en el servidor, FastCGI y los entornos de ejecución modernos.
Para el examen
Formato del tipo MIME: tipo/subtipo
Ejemplos: text/html, text/css, application/json e image/svg+xml
CGI: la primera forma de generar páginas dinámicas
Su problema: lanzaba un proceso por petición
ECMAScript y los estándares ECMA
JavaScript nació en Netscape con el nombre de Mocha, se rebautizó como LiveScript y acabó llamándose JavaScript por razones comerciales, no técnicas: no tiene parentesco con Java. Para que dejara de depender de un fabricante se llevó a normalizar a ECMA, y desde entonces el lenguaje se llama formalmente ECMAScript.
La norma es la ECMA-262. La versión que marcó el salto moderno del lenguaje es la sexta, que se conoce indistintamente como ES6 o ES2015 porque a partir de ahí las ediciones pasaron a nombrarse por año. Es la que trajo let y const, las clases, las funciones flecha, las promesas y los módulos.
| Norma ECMA | Qué normaliza |
|---|---|
| ECMA-262 | ECMAScript, es decir JavaScript |
| ECMA-334 | El lenguaje C# |
| ECMA-335 | CLI, la infraestructura común de lenguajes de .NET |
| ECMA-404 | El formato de intercambio de datos JSON |
ECMA-262 es JavaScript y ECMA-404 es JSON. Es el par de números que más se pregunta, y se confunden con facilidad porque JSON nació dentro de JavaScript.
Para el examen
ECMA-262: JavaScript
ECMA-404: JSON
Nombres anteriores: Mocha y LiveScript
Parentesco con Java: ninguno
Superlenguajes, transpiladores y frameworks de front-end
El navegador solo entiende JavaScript, HTML y CSS. Como esos tres lenguajes se quedan cortos para proyectos grandes, se escribe en lenguajes más ricos y se traducen antes de publicar. A esa traducción se le llama transpilación: no se genera código máquina ni bytecode, sino código fuente de otro lenguaje del mismo nivel. De ahí el nombre alternativo source to source.
| Se escribe en | Se traduce a | Herramientas |
|---|---|---|
| TypeScript, Dart, CoffeeScript, ClojureScript | JavaScript | Babel, Traceur, el propio compilador de TypeScript |
| Less, Sass, Stylus | CSS | Preprocesadores de estilo, con variables, anidamiento y mixins |
| Pug (antes Jade), Handlebars, Mustache | HTML | Motores de plantillas |
Conviene no confundir transpilar con compilar. Un compilador clásico traduce a código objeto ilegible para una persona, como cuando javac convierte un fichero .java en un .class. Un transpilador produce código fuente que se sigue leyendo: TypeScript entra y sale JavaScript.
Sobre esa base se apoyan los frameworks de front-end, que siguen el patrón modelo-vista-modelo de vista (MVVM): separan lo que se pinta de la lógica de negocio y mantienen sincronizados el estado y la interfaz. Los tres nombres de examen son Angular, de Google, React, de Meta, y Vue.js; Ember.js aparece como cuarto habitual.
Para el examen
Transpilar: traducir de un lenguaje a otro del mismo nivel (source to source)
A JavaScript: TypeScript o Dart, con Babel
A CSS: Less, Sass y Stylus
Las herramientas del ciclo de desarrollo de front-end
Un proyecto de front-end moderno no se edita y se sube: se construye. Alrededor de Node.js hay una cadena de herramientas que resuelve cuatro problemas distintos, y el examen suele preguntar cuál resuelve cuál.
| Problema | Herramienta | Fichero o comando |
|---|---|---|
| Gestionar dependencias y versiones | npm o yarn (Bower quedó obsoleto) | package.json, carpeta node_modules |
| Automatizar tareas repetitivas | Gulp o Grunt (obsoletos) | Minificar, transpilar, lanzar pruebas |
| Generar el esqueleto del proyecto | Yeoman (obsoleto), hoy la CLI de cada framework | ng new, create-react-app y equivalentes |
| Empaquetar todo en pocos ficheros | Webpack, Rollup, Parcel, Browserify, FuseBox | Los llamados package bundlers |
| Detectar errores leyendo el código | ESLint, JSHint | Son linters: análisis estático, sin ejecutar |
Los empaquetadores son los que dejaron sin sitio a los automatizadores de tareas: hacen ellos mismos la transpilación, la minificación y la resolución de dependencias, y entregan un puñado de ficheros listos para servir. El conjunto de npm, un empaquetador y una CLI equivale en el mundo JavaScript a lo que Maven hace en Java.
# Arranque típico del panel de un curso con la CLI de Angular
npm install -g @angular/cli # instala la CLI (barra normal, no invertida)
ng new panel-alumno # genera el esqueleto del proyecto
cd panel-alumno
npm install # descarga las dependencias en node_modules
ng serve # levanta el servidor de desarrollo
# Con yarn los comandos equivalentes son:
# yarn init, yarn install, yarn add <paquete>, yarn upgradenpm usa init, install y update; yarn usa init, install, add y upgrade. Los dos leen el mismo package.json y dejan las librerías en node_modules.
Para el examen
Órdenes de npm: init, install y update
Órdenes de yarn: init, install, add y upgrade
Qué comparten: el mismo package.json y el directorio node_modules