diff --git a/18_http.md b/18_http.md
new file mode 100644
index 000000000..e52ab5d97
--- /dev/null
+++ b/18_http.md
@@ -0,0 +1,1431 @@
+{{meta {load_files: ["code/chapter/18_http.js"]}}}
+
+# HTTP y Formularios
+
+{{quote {author: "Roy Fielding", title: "Architectural Styles and the Design of Network-based Software Architectures", chapter: true}
+
+La comunicación debe ser de naturaleza independiente [...] de modo que cada solicitud
+del cliente al servidor debe contener toda la información necesaria para comprenderse
+y no puede hacer uso de ningún contexto almacenado en el servidor.
+
+quote}}
+
+{{index "Fielding, Roy"}}
+
+{{figure {url: "img/chapter_picture_18.jpg", alt: "Picture of a web form on a medieval scroll", chapter: "framed"}}}
+
+{{index [browser, environment]}}
+
+El _Protocolo de transferencia de hipertexto_, mencionado en el [Capítulo
+?](browser#web), es el mecanismo a través del que se solicitan y
+proporcionan datos en la ((World Wide Web)). Este capítulo describe el
+((protocolo)) con más detalle y explica la forma en que el navegador
+de JavaScript tiene acceso a él.
+
+## El protocolo
+
+{{index "IP address"}}
+
+Si escribes _eloquentjs-es.thedojo.mx/18_http.html_ en la
+((barra de direcciones)) de tu navegador, el ((navegador)) primero
+busca la ((dirección)) del servidor asociado con _eloquentjs-es.thedojo.mx_
+e intenta abrir una ((conexión)) ((TCP)) con el ((puerto)) 80, el puerto
+predeterminado para el tráfico ((HTTP)). Si el ((servidor)) existe
+y acepta la conexión, el navegador puede
+enviar algo como esto:
+
+```{lang: http}
+GET /18_http.html HTTP/1.1
+Host: eloquentjs-es.thedojo.mx
+User-Agent: El nombre de tu navegador
+```
+
+Entonces el servidor responde, a través de esa misma conexión.
+
+```{lang: http}
+HTTP/1.1 200 OK
+Content-Length: 65585
+Content-Type: text/html
+Last-Modified: Lun, 08 Ene 2018 10:29:45 GMT
+
+
+... el resto del documento
+```
+
+El navegador toma la parte de la ((respuesta)) después de la línea en
+blanco, es decir el _cuerpo_ (que no debe confundirse con la etiqueta HTML `
`)
+y lo muestra como un documento ((HTML)).
+
+{{index HTTP}}
+
+La información enviada por el cliente es llamada _((request))_.
+Y comienza con esta línea:
+
+```{lang: http}
+GET /18_http.html HTTP/1.1
+```
+
+{{index "DELETE method", "PUT method", "GET method", [method, HTTP]}}
+
+La primera palabra es el _método_ del ((request)).`GET` indicá
+que queremos _obtener_ el recuerso especificado. Otros métodos comunes
+son `DELETE` para eliminar un _resource_, `PUT` oara crearlo o reemplazarlo y
+`POST` para enviarle información. Ten en cuenta que el ((servidor)) no está
+obligado a realizar todas las solicitudes que reciba. Si te acercas a un
+sitio web aleatorio y le dices que `DELETE` su página principal,
+probablemente se negará.
+
+{{index [path, URL], GitHub, [file, resource]}}
+
+La parte que sigue al nombre del método es la ruta del _((resource))_ al
+que se aplica el request. En el caso más simple, un _resource_ es simplemente
+un archivo en el ((servidor)), pero el protocolo no requiere que lo sea.
+Un _resource_ puede ser cualquier cosa que pueda transferirse _como_ archivo.
+Muchos servidores generan las respuestas que producen sobre la marcha.
+Por ejemplo, si abres [_https://github.com/marijnh_](https://github.com/marijnh),
+el servidor busca en su base de datos a un usuario llamado "marijnh", y si encuentra uno,
+generará una página de perfil para ese usuario.
+
+Despues de la ruta del _resource_, la primera línea del _request_ dice
+`HTTP/1.1` para indicar la ((versión)) del ((HTTP)) ((protocolo)) que
+esta usando.
+
+En la practica, muchos sitios utilizan HTTP versión 2, que admite
+los mismos conceptos que la version 1.1 pero es más lento.
+Cuando el resultado de un _request_ es el mismo, al establece conexión con un
+servidor determinado, independientemente de la version
+que se utilice, los navegadores cambiarán automáticamente a la
+versión apropiada del protocolo. Dado que la version
+1.1 es mas sencilla y facil de utilizar, nos centraremos en ella.
+
+{{index "status code"}}
+
+El _response_ comenzará con la version, seguida por el estado de la respuesta,
+primero como un código de estado de tres dígitos y despues como una cadena
+legible por humanos.
+
+```{lang: http}
+HTTP/1.1 200 OK
+```
+
+{{index "200 (HTTP status code)", "error response", "404 (HTTP status code)"}}
+
+Los códigos de estado que comienzan con 2 indican que la solicitud se realizó
+correctamente. Los códigos que comienzan con 4 indican que hubo algún problema
+con el _((request))_. 404 es probablemente el código de estado HTTP más famoso;
+significa que no se pudo encontrar el _resource_. Los códigos que comienzan
+con 5 indican que ocurrió un error en el ((servidor)) que no esta relacionado
+con el _request_.
+
+{{index HTTP}}
+
+{{id headers}}
+
+La primer linea de un _request_ o _response_ puede ir seguida de cualquier número
+de _((header))s_. Las líneas en formato `name: value` especifican información
+adicional sobre el _request_ o _response_. Estos encabezados son parte del
+((response)) ejemplo:
+
+```{lang: null}
+Content-Length: 65585
+Content-Type: text/html
+Last-Modified: Thu, 04 Jan 2018 14:05:30 GMT
+```
+
+{{index "Content-Length header", "Content-Type header", "Last-Modified header"}}
+
+Esto nos indica el tamaño y el tipo del documento del _response_.
+En este caso, es un documento HTML de 65.585 bytes. También nos indica
+cuándo se modificó por última vez ese documento.
+
+{{index "Host header", domain}}
+
+El cliente y el servidor son libres de decidir sin incluir o no en un
+((request)) o ((response)) la mayoría de ((header))s. Pero algunos son
+requeridos. Por ejemplo, el encabezado `Host`, que especifica el
+nombre de host, debe incluirse en un request porque un ((servidor)) podría
+estar respondiendo a diferentes nombres de host en una sola ((dirección IP)), y sin
+ese encabezado, el servidor no sabría el nombre del host que el cliente
+intenta contactar.
+
+
+{{index "GET method", "DELETE method", "PUT method", "POST method", "body (HTTP)"}}
+
+Después de los encabezados, tanto los requests como loss responses pueden incluir
+una línea en blanco seguida del cuerpo, que contiene los datos que se envían.
+Los requests `GET` y `DELETE` no envían ningún dato, pero los requests
+`PUT` y `POST` sí, De manera similar, algunos tipos de response,
+como las respuestas de error, que no requieren un cuerpo.
+
+## Navegadores y HTTP
+
+{{index HTTP, [file, resource]}}
+
+Como vimos en el ejemplo, un navegador hará una solicitud cuando
+ingresemos una ((URL)) en la ((barra de direcciones)). Cuando la página HTML
+resultante hace referencia a otros archivos, como imágenes y archivos JavaScript,
+estos también se recuperan.
+
+{{index parallelism, "GET method"}}
+
+Un ((sitio web)) moderadamente complicado puede incluir fácilmente
+entre 10 y 200 ((recursos)). Para poder obtenerlos rápidamente,
+los navegadores realizarán varias solicitudes `GET` simultáneamente,
+en lugar de esperar las respuestas una a la vez.
+
+Las páginas HTML pueden incluir _((form))s_, que permiten al usuario
+completar información y enviarla al servidor. Este es un ejemplo de un formulario:
+
+```{lang: "text/html"}
+
+```
+
+{{index form, "method attribute", "GET method"}}
+
+Este código describe un formulario con dos campos: uno pequeño que
+solicita un nombre y uno más grande para escribir un mensaje.
+Cuando haces clic en el ((botón)) _Enviar_, se envía el formulario,
+lo que significa que el contenido de su campo se empaqueta en un request
+HTTP y el navegador navega hasta el resultado de esa solicitud.
+
+Cuando el atributo `method` del elemento `` es `GET` (o se omite),
+la información del formulario es añadida al final del `action` URL
+como una _((query string))_ (cadena de consulta).
+El navegador puede realizar una solicitud a esta URL:
+
+```{lang: null}
+GET /example/message.html?name=Jean&message=Yes%3F HTTP/1.1
+```
+
+{{index "ampersand character"}}
+
+El signo de interrogación indica el final de la ruta en la URL
+y el inicio de la consulta. Le siguen pares de nombres y valores,
+correspondientes al atributo `name` de los elementos del formulario
+y el valor de estos, respectivamente.
+Se utiliza el carácter `ampersand` (&) para separar los pares.
+
+{{index [escaping, "in URLs"], "hexadecimal number", "encodeURIComponent function", "decodeURIComponent function"}}
+
+El mensaje codificado en la URL es "¿Sí?", Pero el signo de interrogación
+se reemplaza por un código. Algunos caracteres de las cadenas de consulta
+deben tener formato de escape. El signo de interrogación, representado como `%3F`,
+es un ejemplo de esto. Éxiste una regla no escrita que indica que cada formato
+necesita su propia forma de escapar los caracteres. Este ejemplo, llamado
+_((URL encoding))_ (codificación URL), usa un signo de porcentaje seguido de
+dos dígitos hexadecimales (base 16) que codifican el código del carácter.
+En este caso, 3F, que es 63 en notación decimal, es el código del carácter
+de signo de interrogación. JavaScript proporciona las funciones `encodeURIComponent`
+y `decodeURIComponent` para codificar y decodificar este formato.
+
+```
+console.log(encodeURIComponent("Yes?"));
+// → Yes%3F
+console.log(decodeURIComponent("Yes%3F"));
+// → Yes?
+```
+
+{{index "body (HTTP)", "POST method"}}
+
+Si cambiamos el atributo `method` en el formulario HTML del ejemplo que vimos
+anteriormente con `POST`, la solicitud ((HTTP)) realizada para enviar el ((form))
+utilizará el método `POST` y colocaría la cadena de consulta en el cuerpo de la
+solicitud, en lugar de agregarla al URL.
+
+```{lang: http}
+POST /example/message.html HTTP/1.1
+Content-length: 24
+Content-type: application/x-www-form-urlencoded
+
+name=Jean&message=Yes%3F
+```
+
+Los requests `GET` deben usarse para solicitudes que no tienen efectos secundarios,
+aquellas que simplemente piden información. Las solicitudes que cambian algo en el servidor,
+por ejemplo, la creación de una nueva cuenta o la publicación de un mensaje,
+deben expresarse con otros métodos, como `POST`. El software Client-side (del lado del cliente)
+como los navegadores, sabe que no debe realizar solicitudes `POST` a ciegas, pero a menudo
+realiza solicitudes `GET` implícitamente, por ejemplo, para obtener previamente un
+recurso que el usuario pronto podría necesitar.
+
+Volveremos a los formularios y a cómo interactuar entre ellos desde JavaScript
+[más adelante en este capítulo](http#forms).
+
+{{id fetch}}
+
+## Fetch
+
+{{index "fetch function", "Promise class", [interface, module]}}
+
+The interface through which browser JavaScript can make HTTP
+requests is called `fetch`. Since it is relatively new, it
+conveniently uses promises (which is rare for browser interfaces).
+
+```{test: no}
+fetch("example/data.txt").then(response => {
+ console.log(response.status);
+ // → 200
+ console.log(response.headers.get("Content-Type"));
+ // → text/plain
+});
+```
+
+{{index "Response class", "status property", "headers property"}}
+
+Calling `fetch` returns a promise that resolves to a `Response` object
+holding information about the server's response, such as its status
+code and its headers. The headers are wrapped in a `Map`-like object
+that treats its keys (the header names) as case insensitive because
+header names are not supposed to be case sensitive. This means
+`headers.get("Content-Type")` and `headers.get("content-TYPE")` will
+return the same value.
+
+Note that the promise returned by `fetch` resolves successfully even
+if the server responded with an error code. It _might_ also be
+rejected if there is a network error or if the ((server)) that the
+request is addressed to can't be found.
+
+{{index [path, URL], "relative URL"}}
+
+The first argument to `fetch` is the URL that should be requested.
+When that ((URL)) doesn't start with a protocol name (such as _http:_),
+it is treated as _relative_, which means it is interpreted relative
+to the current document. When it starts with a slash (/), it replaces
+the current path, which is the part after the server name. When it
+does not, the part of the current path up to and including its last
+((slash character)) is put in front of the relative URL.
+
+{{index "text method", "body (HTTP)", "Promise class"}}
+
+To get at the actual content of a response, you can use its `text`
+method. Because the initial promise is resolved as soon as the
+response's headers have been received and because reading the response body
+might take a while longer, this again returns a promise.
+
+```{test: no}
+fetch("example/data.txt")
+ .then(resp => resp.text())
+ .then(text => console.log(text));
+// → This is the content of data.txt
+```
+
+{{index "json method"}}
+
+A similar method, called `json`, returns a promise that
+resolves to the value you get when parsing the body as ((JSON)) or
+rejects if it's not valid JSON.
+
+{{index "GET method", "body (HTTP)", "DELETE method", "method property"}}
+
+By default, `fetch` uses the `GET` method to make its request and
+does not include a request body. You can configure it differently by
+passing an object with extra options as a second argument. For
+example, this request tries to delete `example/data.txt`:
+
+```{test: no}
+fetch("example/data.txt", {method: "DELETE"}).then(resp => {
+ console.log(resp.status);
+ // → 405
+});
+```
+
+{{index "405 (HTTP status code)"}}
+
+The 405 status code means "method not allowed", an HTTP server's way
+of saying "I can't do that".
+
+{{index "Range header", "body property", "headers property"}}
+
+To add a request body, you can include a `body` option. To set
+headers, there's the `headers` option. For example, this request
+includes a `Range` header, which instructs the server to return only
+part of a response.
+
+```{test: no}
+fetch("example/data.txt", {headers: {Range: "bytes=8-19"}})
+ .then(resp => resp.text())
+ .then(console.log);
+// → the content
+```
+
+The browser will automatically add some request ((header))s, such as
+"Host" and those needed for the server to figure out the size of the
+body. But adding your own headers is often useful to include things
+such as authentication information or to tell the server which file
+format you'd like to receive.
+
+{{id http_sandbox}}
+
+## HTTP sandboxing
+
+{{index sandbox, [browser, security]}}
+
+Making ((HTTP)) requests in web page scripts once again raises
+concerns about ((security)). The person who controls the script might
+not have the same interests as the person on whose computer it is
+running. More specifically, if I visit _themafia.org_, I do not want
+its scripts to be able to make a request to _mybank.com_, using
+identifying information from my browser, with instructions to
+transfer all my money to some random account.
+
+For this reason, browsers protect us by disallowing scripts to make
+HTTP requests to other ((domain))s (names such as _themafia.org_ and
+_mybank.com_).
+
+{{index "Access-Control-Allow-Origin header", "cross-domain request"}}
+
+This can be an annoying problem when building systems that want to
+access several domains for legitimate reasons. Fortunately,
+((server))s can include a ((header)) like this in their ((response))
+to explicitly indicate to the browser that it is okay for the request
+to come from another domain:
+
+```{lang: null}
+Access-Control-Allow-Origin: *
+```
+
+## Appreciating HTTP
+
+{{index client, HTTP, [interface, HTTP]}}
+
+When building a system that requires ((communication)) between a
+JavaScript program running in the ((browser)) (client-side) and a
+program on a ((server)) (server-side), there are several different
+ways to model this communication.
+
+{{index [network, abstraction], abstraction}}
+
+A commonly used model is that of _((remote procedure call))s_. In this
+model, communication follows the patterns of normal function calls,
+except that the function is actually running on another machine.
+Calling it involves making a request to the server that includes the
+function's name and arguments. The response to that request contains
+the returned value.
+
+When thinking in terms of remote procedure calls, HTTP is just a
+vehicle for communication, and you will most likely write an
+abstraction layer that hides it entirely.
+
+{{index "media type", "document format", [method, HTTP]}}
+
+Another approach is to build your communication around the concept of
+((resource))s and ((HTTP)) methods. Instead of a remote procedure
+called `addUser`, you use a `PUT` request to `/users/larry`. Instead
+of encoding that user's properties in function arguments, you define a
+JSON document format (or use an existing format) that represents a
+user. The body of the `PUT` request to create a new resource is then
+such a document. A resource is fetched by making a `GET` request to
+the resource's URL (for example, `/user/larry`), which again returns
+the document representing the resource.
+
+This second approach makes it easier to use some of the features that
+HTTP provides, such as support for caching resources (keeping a copy
+on the client for fast access). The concepts used in HTTP, which are
+well designed, can provide a helpful set of principles to design your
+server interface around.
+
+## Security and HTTPS
+
+{{index "man-in-the-middle", security, HTTPS, [network, security]}}
+
+Data traveling over the Internet tends to follow a long, dangerous
+road. To get to its destination, it must hop through anything from
+coffee shop Wi-Fi hotspots to networks controlled by various companies and
+states. At any point along its route it may be inspected or even
+modified.
+
+{{index tampering}}
+
+If it is important that something remain secret, such as the
+((password)) to your ((email)) account, or that it arrive at its
+destination unmodified, such as the account number you transfer money
+to via your bank's website, plain HTTP is not good enough.
+
+{{index cryptography, encryption}}
+
+{{indexsee "Secure HTTP", HTTPS, [browser, security]}}
+
+The secure ((HTTP)) protocol, used for ((URL))s starting with _https://_,
+wraps HTTP traffic in a way that makes it harder to read and tamper
+with. Before exchanging data, the client verifies that the server is
+who it claims to be by asking it to prove that it has a cryptographic
+((certificate)) issued by a certificate authority that the browser
+recognizes. Next, all data going over the ((connection)) is encrypted
+in a way that should prevent eavesdropping and tampering.
+
+Thus, when it works right, ((HTTPS)) prevents other people from
+impersonating the website you are trying to talk to and from
+snooping on your communication. It is not perfect, and there have been
+various incidents where HTTPS failed because of forged or stolen
+certificates and broken software, but it is a _lot_ safer than plain
+HTTP.
+
+{{id forms}}
+
+## Form fields
+
+Forms were originally designed for the pre-JavaScript Web to allow
+web sites to send user-submitted information in an HTTP request. This
+design assumes that interaction with the server always happens by
+navigating to a new page.
+
+{{index [DOM, fields]}}
+
+But their elements are part of the DOM like the rest of the page,
+and the DOM elements that represent form ((field))s support a number
+of properties and events that are not present on other elements. These
+make it possible to inspect and control such input fields with
+JavaScript programs and do things such as adding new functionality to
+a form or using forms and fields as building blocks in a JavaScript
+application.
+
+{{index "form (HTML tag)"}}
+
+A web form consists of any number of input ((field))s grouped in a
+` ` tag. HTML allows several different styles of fields, ranging
+from simple on/off checkboxes to drop-down menus and fields for text
+input. This book won't try to comprehensively discuss all field types,
+but we'll start with a rough overview.
+
+{{index "input (HTML tag)", "type attribute"}}
+
+A lot of field types use the
+` ` tag. This tag's `type` attribute is used to select the
+field's style. These are some commonly used ` ` types:
+
+{{index "password field", checkbox, "radio button", "file field"}}
+
+{{table {cols: [1,5]}}}
+
+| `text` | A single-line ((text field))
+| `password` | Same as `text` but hides the text that is typed
+| `checkbox` | An on/off switch
+| `radio` | (Part of) a ((multiple-choice)) field
+| `file` | Allows the user to choose a file from their computer
+
+{{index "value attribute", "checked attribute", "form (HTML tag)"}}
+
+Form fields do not necessarily have to appear in a ` ` tag. You
+can put them anywhere in a page. Such form-less fields cannot be
+((submit))ted (only a form as a whole can), but when responding to
+input with JavaScript, we often don't want to submit our fields
+normally anyway.
+
+```{lang: "text/html"}
+ (text)
+ (password)
+ (checkbox)
+
+
+ (radio)
+ (file)
+```
+
+{{if book
+
+The fields created with this HTML code look like this:
+
+{{figure {url: "img/form_fields.png", alt: "Various types of input tags",width: "4cm"}}}
+
+if}}
+
+The JavaScript interface for such elements differs with the type of
+the element.
+
+{{index "textarea (HTML tag)", "text field"}}
+
+Multiline text fields have their own tag, ``, mostly because
+using an attribute to specify a multiline starting value would be
+awkward. The `` tag requires a matching ` `
+closing tag and uses the text between those two, instead of the
+`value` attribute, as starting text.
+
+```{lang: "text/html"}
+
+one
+two
+three
+
+```
+
+{{index "select (HTML tag)", "option (HTML tag)", "multiple choice", "drop-down menu"}}
+
+Finally, the `` tag is used to
+create a field that allows the user to select from a number of
+predefined options.
+
+```{lang: "text/html"}
+
+ Pancakes
+ Pudding
+ Ice cream
+
+```
+
+{{if book
+
+Such a field looks like this:
+
+{{figure {url: "img/form_select.png", alt: "A select field", width: "4cm"}}}
+
+if}}
+
+{{index "change event"}}
+
+Whenever the value of a form field changes, it will fire a `"change"`
+event.
+
+## Focus
+
+{{index keyboard, focus}}
+
+{{indexsee "keyboard focus", focus}}
+
+Unlike most elements in HTML documents, form fields can get _keyboard
+((focus))_. When clicked or activated in some other way, they become
+the currently active element and the recipient of keyboard ((input)).
+
+{{index "option (HTML tag)", "select (HTML tag)"}}
+
+Thus, you can type into a ((text field)) only when it is focused. Other
+fields respond differently to keyboard events. For example, a
+`` menu tries to move to the option that contains the text the
+user typed and responds to the arrow keys by moving its selection up
+and down.
+
+{{index "focus method", "blur method", "activeElement property"}}
+
+We can control ((focus)) from JavaScript with the `focus` and `blur`
+methods. The first moves focus to the DOM element it is called on, and
+the second removes focus. The value in `document.activeElement`
+corresponds to the currently focused element.
+
+```{lang: "text/html"}
+
+
+```
+
+{{index "autofocus attribute"}}
+
+For some pages, the user is expected to want to interact with a form
+field immediately. JavaScript can be used to ((focus)) this field when
+the document is loaded, but HTML also provides the `autofocus`
+attribute, which produces the same effect while letting the browser
+know what we are trying to achieve. This gives the browser the option
+to disable the behavior when it is not appropriate, such as when the
+user has put the focus on something else.
+
+{{index "tab key", keyboard, "tabindex attribute", "a (HTML tag)"}}
+
+Browsers traditionally also allow the user to move the focus
+through the document by pressing the [tab]{keyname} key. We can influence the
+order in which elements receive focus with the `tabindex` attribute.
+The following example document will let the focus jump from the text input to
+the OK button, rather than going through the help link first:
+
+```{lang: "text/html", focus: true}
+ (help)
+OK
+```
+
+{{index "tabindex attribute"}}
+
+By default, most types of HTML elements cannot be focused. But you can
+add a `tabindex` attribute to any element that will make it
+focusable. A `tabindex` of -1 makes tabbing skip over an element, even
+if it is normally focusable.
+
+## Disabled fields
+
+{{index "disabled attribute"}}
+
+All ((form)) ((field))s can be _disabled_ through their `disabled`
+attribute. It is an ((attribute)) that can be specified without
+value—the fact that it is present at all disables the element.
+
+```{lang: "text/html"}
+I'm all right
+I'm out
+```
+
+Disabled fields cannot be ((focus))ed or changed, and browsers make
+them look gray and faded.
+
+{{if book
+
+{{figure {url: "img/button_disabled.png", alt: "A disabled button",width: "3cm"}}}
+
+if}}
+
+{{index "user experience"}}
+
+When a program is
+in the process of handling an action caused by some ((button)) or other control
+that might require communication with the server and thus take a
+while, it can be a good idea to
+disable the control until the action finishes. That way, when the user
+gets impatient and clicks it again, they don't accidentally repeat
+their action.
+
+## The form as a whole
+
+{{index "array-like object", "form (HTML tag)", "form property", "elements property"}}
+
+When a ((field)) is contained in a `` element, its DOM element
+will have a `form` property linking back to the form's DOM element.
+The ` ` element, in turn, has a property called `elements` that
+contains an array-like collection of the fields inside it.
+
+{{index "elements property", "name attribute"}}
+
+The `name` attribute of a form field determines the way its value will
+be identified when the form is ((submit))ted. It can also be used as a
+property name when accessing the form's `elements` property, which
+acts both as an array-like object (accessible by number) and a ((map))
+(accessible by name).
+
+```{lang: "text/html"}
+
+ Name:
+ Password:
+ Log in
+
+
+```
+
+{{index "button (HTML tag)", "type attribute", submit, "enter key"}}
+
+A button with a `type` attribute of `submit` will, when pressed,
+cause the form to be submitted. Pressing [enter]{keyname} when a form field is
+focused has the same effect.
+
+{{index "submit event", "event handling", "preventDefault method", "page reload", "GET method", "POST method"}}
+
+Submitting a ((form)) normally means that the ((browser)) navigates to
+the page indicated by the form's `action` attribute, using either a
+`GET` or a `POST` ((request)). But before that happens, a `"submit"`
+event is fired. You can handle this event with JavaScript and prevent
+this default behavior by calling `preventDefault` on the event object.
+
+```{lang: "text/html"}
+
+ Value:
+ Save
+
+
+```
+
+{{index "submit event", validation}}
+
+Intercepting `"submit"` events in JavaScript has various uses. We can
+write code to verify that the values the user entered make sense and
+immediately show an error message instead of submitting the form. Or
+we can disable the regular way of submitting the form entirely, as in
+the example, and have our program handle the input, possibly using
+`fetch` to send it to a server without reloading the page.
+
+## Text fields
+
+{{index "value attribute", "input (HTML tag)", "text field", "textarea (HTML tag)", [DOM, fields], [interface, object]}}
+
+Fields created by `` tags, or ` ` tags with a type of
+`text` or `password`, share a common interface. Their DOM
+elements have a `value` property that holds their current content as a
+string value. Setting this property to another string changes the
+field's content.
+
+{{index "selectionStart property", "selectionEnd property"}}
+
+The
+`selectionStart` and `selectionEnd` properties of ((text field))s give
+us information about the ((cursor)) and ((selection)) in the ((text)).
+When nothing is selected, these two properties hold the same number,
+indicating the position of the cursor. For example, 0 indicates the
+start of the text, and 10 indicates the cursor is after the 10^th^ ((character)).
+When part of the field is selected, the two properties will differ, giving us the
+start and end of the selected text. Like `value`, these properties may
+also be written to.
+
+{{index Khasekhemwy, "textarea (HTML tag)", keyboard, "event handling"}}
+
+Imagine you are writing an article about Khasekhemwy but have some
+trouble spelling his name. The following code wires up a ``
+tag with an event handler that, when you press F2, inserts the string
+"Khasekhemwy" for you.
+
+```{lang: "text/html"}
+
+
+```
+
+{{index "replaceSelection function", "text field"}}
+
+The `replaceSelection`
+function replaces the currently selected part of a text field's
+content with the given word and then moves the ((cursor)) after that
+word so that the user can continue typing.
+
+{{index "change event", "input event"}}
+
+The `"change"` event for a ((text
+field)) does not fire every time something is typed. Rather, it
+fires when the field loses ((focus)) after its content was changed.
+To respond immediately to changes in a text field, you should register
+a handler for the `"input"` event instead, which fires for every
+time the user types a character, deletes text, or otherwise manipulates
+the field's content.
+
+The following example shows a text field and a counter displaying the
+current length of the text in the field:
+
+```{lang: "text/html"}
+ length: 0
+
+```
+
+## Checkboxes and radio buttons
+
+{{index "input (HTML tag)", "checked attribute"}}
+
+A ((checkbox)) field is a binary toggle. Its value can be extracted or
+changed through its `checked` property, which holds a Boolean value.
+
+```{lang: "text/html"}
+
+ Make this page purple
+
+
+```
+
+{{index "for attribute", "id attribute", focus, "label (HTML tag)", labeling}}
+
+The `` tag associates a piece of document with an input
+((field)). Clicking anywhere on the label will activate the field,
+which focuses it and toggles its value when it is a checkbox or radio
+button.
+
+{{index "input (HTML tag)", "multiple-choice"}}
+
+A ((radio button)) is similar to a checkbox, but it's implicitly
+linked to other radio buttons with the same `name` attribute so that
+only one of them can be active at any time.
+
+```{lang: "text/html"}
+Color:
+
+ Orange
+
+
+ Green
+
+
+ Blue
+
+
+```
+
+{{index "name attribute", "querySelectorAll method"}}
+
+The ((square brackets)) in the CSS query given to `querySelectorAll`
+are used to match attributes. It selects elements whose `name`
+attribute is `"color"`.
+
+## Select fields
+
+{{index "select (HTML tag)", "multiple-choice", "option (HTML tag)"}}
+
+Select fields are conceptually similar to radio buttons—they
+also allow the user to choose from a set of options. But where a radio
+button puts the layout of the options under our control, the
+appearance of a `` tag is determined by the browser.
+
+{{index "multiple attribute", "drop-down menu"}}
+
+Select fields also have a variant that is more akin to a list of
+checkboxes, rather than radio boxes. When given the `multiple`
+attribute, a `` tag will allow the user to select any number
+of options, rather than just a single option. This will, in most
+browsers, show up differently than a normal select field, which is
+typically drawn as a _drop-down_ control that shows the options only
+when you open it.
+
+{{index "option (HTML tag)", "value attribute"}}
+
+Each `` tag has a value. This value can be defined with a
+`value` attribute. When that is not given, the ((text)) inside the
+option will count as its value. The `value` property of a ``
+element reflects the currently selected option. For a `multiple`
+field, though, this property doesn't mean much since it will give the
+value of only _one_ of the currently selected options.
+
+{{index "select (HTML tag)", "options property", "selected attribute"}}
+
+The `` tags for a `` field can be accessed as an
+array-like object through the field's `options` property. Each option
+has a property called `selected`, which indicates whether that option
+is currently selected. The property can also be written to select or
+deselect an option.
+
+{{index "multiple attribute", "binary number"}}
+
+This example extracts the selected values from a `multiple` select
+field and uses them to compose a binary number from individual bits.
+Hold [control]{keyname} (or [command]{keyname} on a Mac) to select multiple options.
+
+```{lang: "text/html"}
+
+ 0001
+ 0010
+ 0100
+ 1000
+ = 0
+
+```
+
+## File fields
+
+{{index file, "hard drive", "file system", security, "file field", "input (HTML tag)"}}
+
+File fields were originally designed as
+a way to ((upload)) files from the user's machine through a form.
+In modern browsers, they also provide a way to read such files from
+JavaScript programs. The field acts as a kind of gatekeeper. The
+script cannot simply start reading private files from the user's
+computer, but if the user selects a file in such a field, the browser
+interprets that action to mean that the script may read the file.
+
+A file field usually looks like a button labeled with something like
+"choose file" or "browse", with information about the chosen file next
+to it.
+
+```{lang: "text/html"}
+
+
+```
+
+{{index "multiple attribute", "files property"}}
+
+The `files` property of a
+((file field)) element is an ((array-like object)) (again, not a real
+array) containing the files chosen in the field. It is initially
+empty. The reason there isn't simply a `file` property is that file
+fields also support a `multiple` attribute, which makes it possible to
+select multiple files at the same time.
+
+{{index "File type"}}
+
+Objects in the `files` object have properties such as `name` (the
+filename), `size` (the file's size in bytes, which are chunks of 8
+bits), and `type` (the media type of the file, such as `text/plain` or
+`image/jpeg`).
+
+{{index ["asynchronous programming", "reading files"], "file reading", "FileReader class"}}
+
+{{id filereader}}
+
+What it does not have is a property that contains the content of the
+file. Getting at that is a little more involved. Since reading a file
+from disk can take time, the interface must be asynchronous to avoid
+freezing the document.
+
+```{lang: "text/html"}
+
+
+```
+
+{{index "FileReader class", "load event", "readAsText method", "result property"}}
+
+Reading a file is done by creating a `FileReader` object, registering
+a `"load"` event handler for it, and calling its `readAsText` method,
+giving it the file we want to read. Once loading finishes, the
+reader's `result` property contains the file's content.
+
+{{index "error event", "FileReader class", "Promise class"}}
+
+`FileReader`s also fire an `"error"` event when reading the file fails
+for any reason. The error object itself will end up in the reader's
+`error` property. This interface was designed before promises became
+part of the language. You could wrap it in a promise like this:
+
+```
+function readFileText(file) {
+ return new Promise((resolve, reject) => {
+ let reader = new FileReader();
+ reader.addEventListener(
+ "load", () => resolve(reader.result));
+ reader.addEventListener(
+ "error", () => reject(reader.error));
+ reader.readAsText(file);
+ });
+}
+```
+
+## Storing data client-side
+
+{{index "web application"}}
+
+Simple ((HTML)) pages with a bit of JavaScript can be a great format
+for "((mini application))s"—small helper programs that automate basic
+tasks. By connecting a few form ((field))s with event handlers, you
+can do anything from converting between centimeters and inches to
+computing passwords from a master password and a website name.
+
+{{index persistence, [binding, "as state"], [browser, storage]}}
+
+When such an application needs to remember something between sessions,
+you cannot use JavaScript bindings—those are thrown away every
+time the page is closed. You could set up a server, connect it to the
+Internet, and have your application store something there. We will see
+how to do that in [Chapter ?](node). But that's a lot of extra work
+and complexity. Sometimes it is enough to just keep the data in the
+((browser)).
+
+{{index "localStorage object", "setItem method", "getItem method", "removeItem method"}}
+
+The `localStorage` object can be used to store data in a way that
+survives ((page reload))s. This object allows you to file string
+values under names.
+
+```
+localStorage.setItem("username", "marijn");
+console.log(localStorage.getItem("username"));
+// → marijn
+localStorage.removeItem("username");
+```
+
+{{index "localStorage object"}}
+
+A value in `localStorage` sticks around until it is overwritten, it is
+removed with `removeItem`, or the user clears their local data.
+
+{{index security}}
+
+Sites from different ((domain))s get different storage
+compartments. That means data stored in `localStorage` by a given
+website can, in principle, be read (and overwritten) only by scripts on
+that same site.
+
+{{index "localStorage object"}}
+
+Browsers do enforce a limit on the size of the data a site can store
+in `localStorage`. That restriction, along with the fact that filling
+up people's ((hard drive))s with junk is not really profitable,
+prevents the feature from eating up too much space.
+
+{{index "localStorage object", "note-taking example", "select (HTML tag)", "button (HTML tag)", "textarea (HTML tag)"}}
+
+The following code implements a crude note-taking application. It
+keeps a set of named notes and allows the user to edit notes and
+create new ones.
+
+```{lang: "text/html", startCode: true}
+Notes: Add
+
+
+
+```
+
+{{index "getItem method", JSON, "|| operator", "default value"}}
+
+The script gets its starting state from the `"Notes"` value stored in
+`localStorage` or, if that is missing, creates an example state
+that has only a shopping list in it. Reading a field that does not
+exist from `localStorage` will yield `null`. Passing `null` to
+`JSON.parse` will make it parse the string `"null"` and return `null`.
+Thus, the `||` operator can be used to provide a default value in a
+situation like this.
+
+The `setState` method makes sure the DOM is showing a given state and
+stores the new state to `localStorage`. Event handlers call this
+function to move to a new state.
+
+{{index "Object.assign function", [object, creation], property, "computed property"}}
+
+The use of `Object.assign` in the example is intended to create a new
+object that is a clone of the old `state.notes`, but with one property
+added or overwritten. `Object.assign` takes its first argument and
+adds all properties from any further arguments to it. Thus, giving it
+an empty object will cause it to fill a fresh object. The ((square
+brackets)) notation in the third argument is used to create a property
+whose name is based on some dynamic value.
+
+{{index "sessionStorage object", [browser, storage]}}
+
+There is another object, similar to `localStorage`, called
+`sessionStorage`. The difference between the two is that the content
+of `sessionStorage` is forgotten at the end of each _((session))_,
+which for most browsers means whenever the browser is closed.
+
+## Summary
+
+In this chapter, we discussed how the HTTP protocol works. A _client_
+sends a request, which contains a method (usually `GET`) and a path
+that identifies a resource. The _server_ then decides what to do with
+the request and responds with a status code and a response body. Both
+requests and responses may contain headers that provide additional
+information.
+
+The interface through which browser JavaScript can make HTTP requests
+is called `fetch`. Making a request looks like this:
+
+```
+fetch("/18_http.html").then(r => r.text()).then(text => {
+ console.log(`The page starts with ${text.slice(0, 15)}`);
+});
+```
+
+Browsers make `GET` requests to fetch the resources needed to display
+a web page. A page may also contain forms, which allow information
+entered by the user to be sent as a request for a new page when the
+form is submitted.
+
+HTML can represent various types of form fields, such as text fields,
+checkboxes, multiple-choice fields, and file pickers.
+
+Such fields can be inspected and manipulated with JavaScript. They
+fire the `"change"` event when changed, fire the `"input"` event when text
+is typed, and receive keyboard events when they have keyboard focus.
+Properties like `value` (for text and select fields) or `checked` (for
+checkboxes and radio buttons) are used to read or set the field's
+content.
+
+When a form is submitted, a `"submit"` event is fired on it. A
+JavaScript handler can call `preventDefault` on that event to disable
+the browser's default behavior. Form field elements may also occur
+outside of a form tag.
+
+When the user has selected a file from their local file system in a
+file picker field, the `FileReader` interface can be used to access
+the content of this file from a JavaScript program.
+
+The `localStorage` and `sessionStorage` objects can be used to save
+information in a way that survives page reloads. The first object saves the
+data forever (or until the user decides to clear it), and the second
+saves it until the browser is closed.
+
+## Exercises
+
+### Content negotiation
+
+{{index "Accept header", "media type", "document format", "content negotiation (exercise)"}}
+
+One of the things HTTP can do is called _content negotiation_.
+The `Accept` request header is used to tell the server what type of
+document the client would like to get. Many servers ignore this
+header, but when a server knows of various ways to encode a resource,
+it can look at this header and send the one that the client prefers.
+
+{{index "MIME type"}}
+
+The URL
+[_https://eloquentjavascript.net/author_](https://eloquentjavascript.net/author)
+is configured to respond with either plaintext, HTML, or JSON,
+depending on what the client asks for. These formats are identified by
+the standardized _((media type))s_ `text/plain`, `text/html`, and
+`application/json`.
+
+{{index "headers property", "fetch function"}}
+
+Send requests to fetch all three formats of this resource. Use the
+`headers` property in the options object passed to `fetch` to set the
+header named `Accept` to the desired media type.
+
+Finally, try asking for the media type `application/rainbows+unicorns`
+and see which status code that produces.
+
+{{if interactive
+
+```{test: no}
+// Your code here.
+```
+
+if}}
+
+{{hint
+
+{{index "content negotiation (exercise)"}}
+
+Base your code on the `fetch` examples [earlier in the
+chapter](http#fetch).
+
+{{index "406 (HTTP status code)", "Accept header"}}
+
+Asking for a bogus media type will return a response with code 406,
+"Not acceptable", which is the code a server should return when it
+can't fulfill the `Accept` header.
+
+hint}}
+
+### A JavaScript workbench
+
+{{index "JavaScript console", "workbench (exercise)"}}
+
+Build an interface that allows people to type and run pieces of
+JavaScript code.
+
+{{index "textarea (HTML tag)", "button (HTML tag)", "Function constructor", "error message"}}
+
+Put a button next to a `` field that, when pressed, uses
+the `Function` constructor we saw in [Chapter ?](modules#eval) to wrap
+the text in a function and call it. Convert the return value of the
+function, or any error it raises, to a string and display it below the
+text field.
+
+{{if interactive
+
+```{lang: "text/html", test: no}
+return "hi";
+Run
+
+
+
+```
+
+if}}
+
+{{hint
+
+{{index "click event", "mousedown event", "Function constructor", "workbench (exercise)"}}
+
+Use `document.querySelector` or `document.getElementById` to get
+access to the elements defined in your HTML. An event handler for
+`"click"` or `"mousedown"` events on the button can get the `value`
+property of the text field and call `Function` on it.
+
+{{index "try keyword", "exception handling"}}
+
+Make sure you wrap both the call to `Function` and the call to its
+result in a `try` block so you can catch the exceptions it
+produces. In this case, we really don't know what type of exception we
+are looking for, so catch everything.
+
+{{index "textContent property", output, text, "createTextNode method", "newline character"}}
+
+The `textContent` property of the output element can be used to fill
+it with a string message. Or, if you want to keep the old content
+around, create a new text node using `document.createTextNode` and
+append it to the element. Remember to add a newline character to the
+end so that not all output appears on a single line.
+
+hint}}
+
+### Conway's Game of Life
+
+{{index "game of life (exercise)", "artificial life", "Conway's Game of Life"}}
+
+Conway's Game of Life is a simple ((simulation)) that creates
+artificial "life" on a ((grid)), each cell of which is either alive or
+not. Each ((generation)) (turn), the following rules are applied:
+
+* Any live ((cell)) with fewer than two or more than three live
+ ((neighbor))s dies.
+
+* Any live cell with two or three live neighbors lives on to the next
+ generation.
+
+* Any dead cell with exactly three live neighbors becomes a live cell.
+
+A _neighbor_ is defined as any adjacent cell, including diagonally
+adjacent ones.
+
+{{index "pure function"}}
+
+Note that these rules are applied to the whole grid at once, not one
+square at a time. That means the counting of neighbors is based on the
+situation at the start of the generation, and changes happening to
+neighbor cells during this generation should not influence the new
+state of a given cell.
+
+{{index "Math.random function"}}
+
+Implement this game using whichever ((data structure)) you find
+appropriate. Use `Math.random` to populate the grid with a random
+pattern initially. Display it as a grid of ((checkbox)) ((field))s,
+with a ((button)) next to it to advance to the next ((generation)).
+When the user checks or unchecks the checkboxes, their changes should
+be included when computing the next generation.
+
+{{if interactive
+
+```{lang: "text/html", test: no}
+
+Next generation
+
+
+```
+
+if}}
+
+{{hint
+
+{{index "game of life (exercise)"}}
+
+To solve the problem of having the changes conceptually happen at the
+same time, try to see the computation of a ((generation)) as a ((pure
+function)), which takes one ((grid)) and produces a new grid that
+represents the next turn.
+
+Representing the matrix can be done in the way shown in [Chapter
+?](object#matrix). You can count live ((neighbor))s with two nested
+loops, looping over adjacent coordinates in both dimensions. Take care
+not to count cells outside of the field and to ignore the cell in the
+center, whose neighbors we are counting.
+
+{{index "event handling", "change event"}}
+
+Ensuring that changes to ((checkbox))es take effect on the next generation
+can be done in two ways. An event handler could notice these changes
+and update the current grid to reflect them, or you could generate a
+fresh grid from the values in the checkboxes before computing the next
+turn.
+
+If you choose to go with event handlers, you might want to attach
+((attribute))s that identify the position that each checkbox
+corresponds to so that it is easy to find out which cell to change.
+
+{{index drawing, "table (HTML tag)", "br (HTML tag)"}}
+
+To draw the grid of checkboxes, you can either use a `` element
+(see [Chapter ?](dom#exercise_table)) or simply put them all in the
+same element and put ` ` (line break) elements between the rows.
+
+hint}}
diff --git a/html/index.html b/html/index.html
index b18af574f..15ae04bac 100644
--- a/html/index.html
+++ b/html/index.html
@@ -114,9 +114,9 @@ (Parte 1: Languaje)
The Document Object Model
- Handling Events
+