summaryrefslogtreecommitdiff
path: root/contenidos.md
blob: 60145123cc421c1f66ab4ba90622631d21328165 (plain)
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
---
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.

Con la aparición de ES6 (ECMAScript 6) se añaden `let` y `const` cuyo ámbito
(*scope*) se limita al bloque actual.

## 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 valores, cada uno
asignado a una clave.

> 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`.

[csstricks-js-oop-flavors]: https://css-tricks.com/the-flavors-of-object-oriented-programming-in-javascript/

#### 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 algunas de
las formas habituales de crear nuevos objetos. Aunque hay otras.

[new]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new