1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
|
---
links-as-notes: true
toc: true
title: Documentación
subtitle: Desarrollo de aplicaciones con tecnologías Web
author: "`Ekaitz Zárraga <ekaitz@elenq.tech>`"
author-meta: Ekaitz Zárraga
lang: es-ES
polyglossia-lang:
name: spanish
license: CC-BY-SA
---
# Introducción a la Web
La Web nace como una tecnología para intercambio de documentos de hipertexto.
Para habilitar el intercambio de hipertexto hace uso de tres componentes
principales:
- Protocolo de intercambio -> HTTP
- Identificación de documentos en la red -> URL
- Formato de documentos que soporten enlaces de hipertexto -> HTML
Para poder navegar la red de documentos de hipertexto es necesario un software
concreto: un navegador. El navegador tiene diferentes tareas:
- Visualizar documentos
- Descargar documentos
- Permitir la navegación a otros documentos (navegar = descargar + visualizar)
Los navegadores modernos realizan muchas más tareas de las descritas, pero esa
es su esencia.
# Protocolo de intercambio: HTTP(s)
*HyperText Transfer Protocol*.
Protocolo a nivel de aplicación, que funciona sobre TCP.
Es un protocolo de intercambio de mensajes en formato texto.
Dos versiones: segura (HTTPs), cifrada, y no segura (HTTP), comunicación cruda
sin cifrar.
Arquitectura cliente-servidor:
- El cliente envía consultas
- El servidor responde
Diferentes métodos para consultar:
- *GET*
- *HEAD*
- *OPTIONS*
- *TRACE*
- *PUT*
- *POST*
- *PATCH*
- *DELETE*
- *CONNECT*
Diferentes modos de respuesta
- `1XX` - *Info*
- `2XX` - *OK*
- `3XX` - *Redirect*
- `4XX` - *Client error*
- `5XX` - *Server error*
Estructura de las peticiones y respuestas:
- Método / Código de respuesta
- Cabeceras (*headers*): parejas clave-valor que indican conceptos adicionales
opcionales, relacionados con la conexión
- Cuerpo (*body*): Campo opcional para envío de datos
Petición de ejemplo (Wikipedia):
GET / HTTP/1.1
Host: www.example.com
Respuesta de ejemplo (Wikipedia):
HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 138
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
ETag: "3f80f-1b6-3e1cb03b"
Accept-Ranges: bytes
Connection: close
<html>
<head>
<title>An Example Page</title>
</head>
<body>
<p>Hello World, this is a very simple HTML document.</p>
</body>
</html>
Protocolo **sin estado** usa otros mecanismos para mantener el estado
(sesiones):
- Cookies: se obtienen por la cabecera Set-Cookie entregada por el servidor y
se devuelven en la cabecera Cookie
- Campos ocultos en formularios
- Tokens: En la cabecera, en cuerpo de la consulta o, a veces, en el
querystring
> Esto se verá más adelante
# Identificador de documentos en la red: URL
El esquema completo de un identificador de documento en la red es el siguiente:
```
schema://user:password@host:port/path?querystring#anchor
```
Los campos indicados en la URL son en su mayoría opcionales. En la web,
normalmente no se utilizan el campo `user` ni el campo `password`, porque no es
una forma segura de conectars, así que el URL queda así (se elimina el caracter
`@`):
```
schema://host:port/path?querystring#anchor
```
- El `schema` se refiere al *protocolo* de comunicación a utilizar. En el caso
de la web, será `http` o `https`, siendo preferible el segundo para
conexiones cuyo contenido deba protegerse.
- El `host` indica un identificador de un equipo. Puede ser un nombre de
dominio o una dirección IP.
- El `puerto` puede ignorarse (quitando también los dos puntos, `:`), y en tal
caso tomará por defecto el valor del puerto asignado al `schema` elegido: 80
para HTTP y 443 para HTTPs.
- El `path` identifica el documento a seleccionar. Se indica mediante un `path`
estilo UNIX desde la raíz del servidor.
- El `querystring` indica información adicional de la consulta, su formato es
el de parejas *clave* y *valor*, separadas por `&`. Con este formato:
`?clave=valor&clave2=valor2&clave3=valor3`
- El `anchor` se refiere a un *ancla* que no se envía en la petición pero el
navegador utiliza para mover la vista de la página a la zona indicada por el
*ancla*, normalmente mediante un atributo `id` en una etiqueta HTML.
## URL relativas y absolutas
En caso de que una URL se reciba en el contenido de un documento, no es
necesario incluir en ella el `host`, el `schema`, etc. para señalar a otro
documento dentro del mismo `host`. Por ejemplo, si se entrega la página:
`https://server.com/pages/index.html`, y en el contenido de ésta existe un
enlace a la URL `/css/style.css`, el navegador resolverá la URL completa a ese
recurso usando la información de la URL actual. Es decir, creará
`https://server.com/css/style.css`.
Además, el navegador tratará las URLs que sólo incluyan el `path` pero que no
parta desde la raíz (`/`) como URLs relativas.
> El formato del `path` en la funciona como en un sistema de archivos de UNIX.
> Igual que en el sistema de archivos UNIX, usar `..` se refiere a la carpeta
> superior.
- Las URL **absolutas** parten siempre desde la raíz `/` e indican qué
documento debe accederse desde la raíz del servidor. Ejemplo:
`/css/style.css`
- Las URL **relativas** se resuelven desde el documento actual. Ejemplo:
`usuario.html`. Estas URLs por sí mismas no identifican de forma inequívoca
un documento, son dependientes del documento donde están escritas. Por
ejemplo, si `/paginas/index.html` tiene un enlace a `usuario.html`, éste se
resolverá a `/paginas/usuario.html` pero si la página con el enlace es
simplemente `/index.html` éste se resolverá a `/usuario.html`.
Conocer los diferentes tipos de URL es muy útil a la hora de estructurar el
contenido de modo que sea fácil de reorganizar.
Tratar de reducir la longitud de las URLs escritas en un documento HTML es
fundamental para facilitar la lectura del documento.
# HTML
*HTML: HyperText Markup Language*
HTML es un **formato semántico** basado en XML.
Para aprender HTML lo mejor es seguir la documentación en [MDN Web
Docs](https://developer.mozilla.org/en-US/docs/Learn/HTML)
Muestra contenido, basándose en su significado lingüístico/lógico: párrafo
(`p`), imagen (`img`), enlace (`a`), sección (`section`), artículo (`article`),
cita (`quote`, `blockquote`), títulos de diferentes niveles (`h1`, `h2`...),
etc
## Sintaxis HTML
``` xml
<tag attr="valor" attr2="valor2">
cuerpo
</tag>
```
También existen elementos vacíos, cuya etiqueta de apertura también aplica el
cierre, ya que no pueden tener contenido:
``` html
<tag attr="valor" />
```
## Un documento HTML
Plantilla de un documento HTML mínimo:
``` html
<!DOCTYPE html> <!-- Indica HTML5 -->
<html>
<head>
<!-- Definición de la codificación del texto -->
<meta charset="utf-8">
<!-- Interesante para responsive/mobile-first -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Título de HTML mínimo</title>
<meta name="author" content="Ekaitz Zárraga">
<meta name="description" content="Un documento HTML mínimo">
</head>
<body>
...
</body>
</html>
```
## La cabecera (head)
El HTML también sirve para indicar metadatos para que el navegador conozca
información adicional sobre el documento. Estos se incluyen en el apartado
`<head>`.
Algunos interesantes son:
- La declaración del encoding: `<meta charset="utf8"/>`
- La declaración de viewport, interesante para visualización en dispositivos
móviles:
`<meta name="viewport" content="width=device-width, initial-scale=1">`
- El título de la página: `<title>`
- La inclusión de documentos relacionados como hojas de estilo e iconos
mediante `<link>`
## El cuerpo (body)
El cuerpo (`<body>`) del HTML debe incluir el apartado visible del documento.
Usa etiquetas semánticas para describir el contenido. Algunos ejemplos:
- `<main>`: Indica la parte principal del contenido del documento.
- `<section>`: Indica una sección del documento.
- `<article>`: Indica una pieza de información que se puede considerar una
entidad única.
Existen muchos componentes HTML. [MDN mantiene una referencia
actualizada][html-ref] de todos los componentes HTML disponibles, su
significado, su compatibilidad con los principales navegadores y una detallada
explicación de qué atributos estándar pueden utilizar.
[html-ref]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element
### Formularios
Los formularios son un componente muy importante de la web.
> TODO discutir los formularios cuando haya un back-end con el que probar
# CSS
*CSS: Cascading StyleSheets*
El HTML sólo almacena información semántica. Las hojas de estilos son
documentos adicionales que pueden enlazarse a documentos HTML para indicar el
estilo de éstos.
Para aprender CSS lo mejor es seguir la documentación de [MDN Web
Docs][css]
[css]: https://developer.mozilla.org/en-US/docs/Learn/CSS
Este es el formato de una regla CSS mínima:
``` css
selector {
propiedad: valor; /* Esta pareja se conoce como "declaración" */
}
```
Los [selectores][selector] funcionan en [cascada][cascade], de más genérico a
más concreto (especificidad, *specificity*). Siendo los más concretos aplicados
después, añadiendo sobre (y sobreescribiendo) las declaraciones aplicadas
previamente. El órden de declaración también es relevante.
[selector]: https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors
[cascade]: https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_and_inheritance
> Recientemente se ha añadido el concepto [*Cascade
> Layer*](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_layers)
> lo que permite controlar de forma más avanzada los conceptos de especificidad
> y cascada.
La [herencia][cascade] también es un concepto importante. Indica que si un
elemento está contenido en otro hereda las propiedades del componente padre.
Por ejemplo, si un `body` define la fuente con un tamaño concreto, todos sus
hijos (y los hijos de estos) aplicarán ese tamaño de fuente, a no ser que se
especifique lo contrario. La herencia permite, por tanto, aplicar propiedades a
objetos sin tener que seleccionarlos de forma directa con un selector. Esto
también significa que mover un elemento HTML de un contenedor a otro puede
cambiar su estilo, debido a que puede heredar nuevas reglas CSS de su nuevo
contenedor.
Aprender CSS requiere de tiempo, ya que existen varios tipos de selectores y
combinaciones entre ellos e infinidad de propiedades, cada una con una gran
variedad de valores posibles. Una vez entendidos los conceptos de la [guía de
MDN][css] de forma general, la mejor manera de aprender es ir trabajando y
aprendiendo a realizar operaciones concretas con el tiempo. Tener los
conceptos básicos es primordial, eso sí, pero tampoco son demasiados.
# JavaScript
[Curso rápido de JavaScript][js-crash]
[Curso de JavaScript][js]
[Curso detallado de JavaScript][js-deep]
[Contexto de las tecnologías de JavaScript][js-overview]
[js-crash]: https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics
[js]: https://developer.mozilla.org/en-US/docs/Learn/JavaScript
[js-deep]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide
[js-overview]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/JavaScript_technologies_overview
La estructura básica del lenguaje es primordial conocer. Diferenciar los tipos
de dato básicos, qué es una **sentencia** (*statement*) y qué es una
**expresión** (*expression*).
En JavaScript las funciones son valores, como cualquier otro. Y pueden
recibirse como argumentos y retornarse como valores de retorno.
## Scope
Las variables declaradas con `var` viven en todo el cuerpo de la función donde
se declararon. Aplica [*hoisting*][hoisting]. Las declaraciones de función son
equivalentes a usar `var`.
[hoisting]: https://developer.mozilla.org/en-US/docs/Glossary/Hoisting
Con la aparición de ES6 (ECMAScript 6) se añaden `let` y `const` cuyo ámbito
(*scope*) se limita al bloque actual. No aplica [*hoisting*][hoisting].
## Closures
El *scope* (ámbito) en JavaScript es **léxico** (*lexical scope*) y para
implementarlo se utilizan *closures*. Una *closure* aparece cuando una función
captura el contexto en el que fue creada para recordar una o más variables:
``` javascript
function incrementador( incremento ){
return (function (valor){
// Se captura el contexto porque `incremento` no está definido en la
// función interna, sino en `incrementador`
return valor + incremento;
})
}
let masDiez = incrementador (10);
let masVeinte = incrementador (20);
masDiez(1) // => 11
masVeinte(1) // => 21
```
## Objetos
Los objetos son fundamentales en JavaScript. Son colecciones de valores, cada
uno asignado a una clave (string).
> Los `Array` son realmente un tipo de objeto con claves numéricas
### Programación orientada a objetos (OOP)
Conceptos principales de la **programación orientada a objetos basada en
clases**:
- **Polimorfismo**: no es aplicable en JavaScript, porque al ser un lenguaje
dinámico se acerca más al
[*duck-typing*](https://en.wikipedia.org/wiki/Duck_typing).
- **Herencia**: que las clases puedan definirse como subclases de otras,
adquiriendo sus características. Las subclases pueden especificar
comportamiento propio sobreescribiendo el comportamiento de la superclase.
- **Encapsulación**: aislar los campos internos de los objetos del exterior
para mantener sus invariantes y asegurarse de que la información dentro del
objeto es siempre coherente.
- **Identidad**: que cada objeto tenga noción de sí mismo. Se realiza mediante
el `this`.
#### Orientación a prototipos
**Realmente JavaScript implementa un sistema de orientación a objetos basado en
prototipos** que permite emular el comportamiento de un sistema basado en
clases, pero que es en realidad mucho más flexible.
La programación orientada a objetos basada en prototipos nace con el objetivo
de clasificar los objetos en función de su *semejanza* a otros, en lugar de si
pertenecen o no a una *clase*. Pero la *semejanza* es un concepto tan fuerte
que realmente permite implementar clases.
[La guía básica de MDN introduce estos conceptos][js-oop]
[js-oop]: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects
Los objetos de JavaScript pueden tener un **prototipo** (*prototype*). El
prototipo es otro objeto. Cuando se hace referencia a una propiedad o método de
un objeto si éste no lo tiene entre sus elementos, se busca en su prototipo.
Los prototipos también pueden tener prototipos. Esta cadena de búsqueda se
conoce como *prototype chain* (cadena de prototipos) y es la que permite
implementar lógicas de relación entre objetos, ya sean basadas en *clases* o en
*semejanza*. Es un mecanismo simple pero muy poderoso.
Debida a la flexibilidad del lenguaje [hay muchas formas de programar mediante
orientación a objetos en JavaScript][csstricks-js-oop-flavors]. La forma más
moderna se introdujo en ES6: `class`, pero es equivalente al sistema clásico
con funciones constructoras y el operador `new`. [Este artículo muestra la
orientación a objetos de forma incremental][oop-codecamp].
[csstricks-js-oop-flavors]: https://css-tricks.com/the-flavors-of-object-oriented-programming-in-javascript/
[oop-codecamp]: https://www.freecodecamp.org/news/a-beginners-guide-to-javascripts-prototype/
#### Identidad
En JavaScript es muy importante controlar la identidad de los objetos: el
`this`.
En ocasiones, como al enviar un método de un objeto como argumento a una
función, el `this` se pierde y el método pierde su identidad. Es por eso que
debe controlarse con mucho cuidado.
Un ejemplo:
``` javascript
function Human(name){
this.name = name;
this.greet = function(){
console.log(`Hola, soy ${this.name}`);
}
}
let ekaitz = new Human("Ekaitz");
ekaitz.greet() // => "Hola, soy Ekaitz"
setTimeout(ekaitz.greet, 100); // => "Hola, soy"
// Al separar el método de su objeto, se pierde el `this`, que se vuelve
// undefined, y no se imprime en pantalla
setTimeout(ekaitz.greet.bind(ekaitz), 100) // => "Hola, soy Ekaitz"
// Gracias al método `bind` de las funciones, es posible asignar el this para
// el futuro
```
Otro operador interesante a comprender es [`new`][new], que habilita la forma
más cómoda y usada de crear nuevos objetos y asignarles un prototipo
automáticamente.
[new]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new
### JSON
JSON es la notación de objetos de JavaScript (*JavaScript Object Notation*),
una forma de codificar objetos de JavaScript en texto para facilitar su
intercambio. Es muy común (y sencillo), por lo que debe conocerse en detalle.
Desde JavaScript, convertir JSON a un objeto y viceversa es trivial:
``` javascript
JSON.parse( texto_json ) // Devuelve un objeto obtenido desde el JSON
JSON.stringify( objeto ) // Devuelve un string JSON con el contenido del objeto
```
## Asincronía
El entorno de ejecución de JavaScript (*Runtime*) está diseñado de forma
asíncrona, alrededor de un bucle de eventos (*Event Loop*). La mayor parte de
las operaciones que requieren algún tipo de espera se procesan en un segundo
plano por parte del runtime y cuando se resuelven son encoladas para que el
programa las procese más tarde.
Los procesos encolados sólo se resuelven cuando la pila de ejecución está
vacía, por lo que es importante liberar la ejecución lo antes posible y
permitir así que el runtime pueda realizar su trabajo.
Este sistema es muy característico de JavaScript y debe conocerse en detalle.
Para más información, visitar [la documentación de MDN][event-loop] o ver [la
famosísima charla de Philip Roberts][charla-jsconf].
[event-loop]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
[charla-jsconf]: https://www.youtube.com/watch?v=8aGhZQkoFbQ
### Promesas
Las promesas son un sistema elegante para resolver los casos de ejecución de
código asíncrono evitando concatenar muchos *callbacks*.
Las promesas son objetos con dos campos principales. Uno que almacena su estado
y otro que almacena su valor, en caso de que el estado sea el adecuado.
El estado de una promesa puede tener uno de estos tres valores:
- `"pending"` para representar que la promesa no se ha resuelto aún
- `"fulfilled"` para representar que la promesa ha sido resuelta correctamente
y por tanto ya tiene un valor disponible
- `"rejected"` para representar que ha ocurrido un error en la resolución de la
promesa y no ha podido resolverse
Las promesas aportan dos métodos principales, para gestionar el código
asíncrono:
- `then( funcion )` la función enviada se ejecutará cuando la promesa se
resuelva, recibiendo como argumento el valor de la promesa. Si la función
enviada retorna un valor, éste se envolverá en una promesa nueva para poder
resolverla con un `then` concatenado
- `catch( función )` la función enviada se ejecutará cuando la promesa falle
con alguna excepción
Las llamadas a `then` pueden concatenarse para realizar operaciones de forma
secuencial (este es el interés principal de las promesas):
``` javascript
function obtenerDitto(){
fetch("https://pokeapi.co/api/v2/pokemon/ditto") // fetch retorna una promesa
.then((r)=>r.json()) // Procesa la respuesta como JSON, y retorna otra promesa
.then((data)=>console.log(data)) // Recibe los datos ya procesados
.catch( procesarError ) // Captura cualquier error ocurrido en el proceso
}
```
#### `async` y `await`
Las palabras reservadas `async` y `await` son azúcar sintáctico (*syntactic
sugar*) sobre el sistema de promesas. Definir una función como `async` permite
realizar la operación `await` dentro de ésta, permitiendo tratar código
asíncrono de forma similar al código síncrono.
El ejemplo anterior traducido a esta sintaxis:
``` javascript
async function obtenerDitto(){
try {
let respuesta = await fetch("https://pokeapi.co/api/v2/pokemon/ditto");
let data = await respuesta.json();
console.log(data);
} catch( err ) {
procesarError(err);
}
}
```
## Resumen
El JavaScript aquí mencionado cubre casi todo el uso básico. La [guía
profunda][js-deep] explica todo en mucho más detalle y añade más información.
# Programación del lado de cliente
## Web APIs
Las Web APIs del navegador aportan a JavaScript infinidad de funcionalidades
que le permiten operar con éste.
> NOTA: en el lado del servidor la mayoría de las Web APIs no están
> disponibles, pero hay otras que realizan tareas más relacionadas con el lado
> del servidor: acceso al sistema de archivos, sockets, etc.
Un gran ejemplo del uso de la API Canvas, gestión de eventos y la API de audio
es la implementación del [Space Invaders de Susam Pal][space-invaders].
[space-invaders]: https://github.com/susam/invaders
### DOM
El DOM (*Document Object Model*) es la representación del documento en la
memoria. Esto es, la forma en la que el navegador entiende el documento HTML,
su estilo y funcionalidad.
> Esta API no se limita al navegador, sino que puede implementarse en otros
> entornos y lenguajes. Simplemente describe una forma de interactuar con este
> sistema de representación.
La API del DOM permite acceder al DOM e interactuar con él de forma imperativa.
El DOM es un árbol de elementos. Para que algo se visualice es necesario
añadirlo al árbol principal, el método `document.createElement(tag)` crea un
nuevo elemento, pero aislado del árbol. Este elemento deberá engancharse al
árbol para que se procese y visualice.
La [introducción de MDN sobre el DOM es bastante accesible][dom-mdn]. La
documentación de referencia puede ser demasiado complicada.
[dom-mdn]: https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction
### Peticiones Web: fetch
La API fetch es el método moderno para realizar peticiones Web. Anteriormente
esta funcionalidad se realizaba mediante una API mucho menos amigable conocida
como XHR (*XML HTTP Request*).
La API fetch está basada en promesas y su uso básico se muestra en el apartado
previo sobre éstas.
También puede realizar peticiones complejas, procesar datos en streaming, y
un largo, etc.
[La documentación de MDN describe el uso básico de fetch en la guía
correspondiente][fetch-mdn]
[fetch-mdn]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
## Librerías Front End comunes
### Mithril
Es un mini-framework basado en componentes. Extremadamente sencillo pero muy
potente. Dispone de funcionalidades para:
- Routing
- Peticiones Web simplificadas basadas en promesas (similares a `fetch`)
- Renderizado de componentes
- Actualización de componentes automática cuando su estado cambia
- Soporta sintaxis JSX mediante plugins
Es diminuto (~1kLoC) por lo que puede estudiarse con facilidad.
### React
[Tutorial de react en video][react-tutorial]
[react-tutorial]: https://www.youtube.com/watch?v=QFaFIcGhPoM&list=PLC3y8-rFHvwgg3vaYJgHGnModB54rxOk3&index=1
# Programación en el lado del servidor
En este curso se usa el entorno de ejecución NodeJS para trabajar en el lado
del servidor, que también se programa en JavaScript.
NodeJS es diferente que el entorno de ejecución de JavaScript en el navegador.
En en lado del servidor las Web APIs no están disponibles del mismo modo que en
el navegador, ya que el entorno en el que se ejecuta es diferente: el navegador
es un programa visual, interactivo diseñado para hacer consultas Web que aporta
JavaScript como un lenguaje de extensiones mientras que NodeJS es un entorno de
ejecución de aplicaciones que por defecto no es gráfico.
El entorno del servidor se parece más a la programación clásica, ya que no se
ejecuta en el Sandbox del navegador: se dispone de acceso a archivos,
interfaces de red y otros recursos del sistema, que en el navegador no están
disponibles.
## Frameworks de Back End
### Express
[Express][express] es un framework (para NodeJS) de programación Web de
lado del servidor. Su funcionamiento interno se centra en un único concepto: el
**middleware**.
En Express el *middleware* se refiere a funciones que se ejecutan al recibir
consultas Web.
Cada función *middleware* se registra en la aplicación, para una ruta y método
HTTP y se ejecutará cuando esta ruta y método sean accedidos por algún cliente.
Como cada ruta y método pueden registrar varias funciones de *middleware* es
responsabilidad de cada función de *middleware* decidir si se pasa a la
siguiente o si se envía una respuesta, obviando el *middleware* restante.
La [documentación de Express dispone de unas guías que describen el
funcionamiento a la perfección][express]
[express]: https://expressjs.com
### Flask
[Flask][flask] es un framework de programación en el lado del servidor, muy
similar a Express, pero para el lenguaje Python.
[flask]: https://flask.palletsprojects.com/en/2.2.x/
### Otros
Hay infinidad de lenguajes y frameworks en los que realizar aplicaciones web
del lado de servidor. Aquí una lista de algunos muy usados:
- PHP: Laravel, Symfony
- Python: Flask, Django
- Java: Spring
- Ruby: Sinatra, Ruby on Rails
- NodeJS: Express, Koa
## Anatomía de una aplicación Web
Una aplicación Web del lado del servidor debe recibir consultas de los
clientes, procesarlas y retornar una respuesta.
Las repuestas suelen ser documentos HTML, frecuentemente construidos de forma
dinámica en el servidor basándose en plantillas de documentos escritas
previamente e información adicional, normalmente obtenida desde una base de
datos.
Además del HTML, las aplicaciones Web suelen ser capaces de servir archivos
estáticos tales como imágenes, archivos JavaScript para el lado del cliente,
hojas de estilos CSS y otros. Estos se entregarán directamente, sin procesar.
<!--
# Apéndice: Test-Driven development (TDD)
[Un tutorial con Jest muy sencillo][jest-tuto]
[jest-tuto]: https://www.youtube.com/watch?v=G43sWqt8T98
[jest-tuto-mejor]: https://www.youtube.com/watch?v=FgnxcUQ5vho
[intro-tdd]: https://khalilstemmler.com/articles/test-driven-development/introduction-to-tdd/
# Apéndice: El gestor de paquetes de NodeJS (NPM)
-->
|