Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Web Development

Http Conciso: Mensajes HTTP

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called HTTP Succinctly.
HTTP Succinctly: HTTP Resources
HTTP Succinctly: HTTP Connections

Spanish (Español) translation by Jonathan Samines (you can also view the original English article)

En éste capítulo, veremos el interior de los mensajes intercambiados en una transacción HTTP. Aprenderemos acerca de los tipos de mensajes, las cabeceras HTTP y los códigos de estado. Entender que hay dentro de un mensaje HTTP es de vital importancia para los desarrolladores que trabajan en la web. No solo construirás mejores aplicaciones respondiendo con los tipos de mensaje correctos, sino que también serás capaz de detectar y depurar problemas cuando las aplicaciones web no estén funcionando.


Solicitudes y Respuestas

Imagínate caminando hacía un extraño en un aeropuerto y preguntarle, "¿Sabes qué hora es?" Para que el extraño responda con la hora correcta, unas pocas cosas tienen que estar en su lugar. Primero, el extraño tiene que entender tu pregunta, porque si el o ella no sabe inglés, el o ella podría no ser capaz de dar una respuesta. Segundo, el extraño necesitará acceso al reloj o algún otro dispositivo que almacene el tiempo.

Esta analogía del aeropuerto es similar a cómo HTTP funciona. Tú, el cliente, necesita un recurso de alguna otra parte (siendo el recurso la información sobre la hora del día). Así que haces una solicitud a la otra parte utilizando un lenguaje y un vocabulario que esperas que la otra parte entienda. Si la otra parte entiende tu solicitud y tiene el recurso disponible, puede responder. Si entiende la solicitud pero no tiene el recurso, aún puede responder y decirte que no lo sabe. Si la otra parte no entiende lo que estás diciendo, podrías no obtener ninguna respuesta.

HTTP es un protocolo de solicitud y respuesta. Un cliente envía una solicitud HTTP al servidor utilizando un mensaje cuidadosamente formateado que el servidor entenderá. Un servidor responde enviando una respuesta HTTP que el cliente entenderá. La solicitud y la respuesta son dos tipos diferentes de mensajes que son intercambiados en una única transacción HTTP. El estándar HTTP define el contenido de éstos mensajes de solicitud y respuesta así que todos aquellos que hablen "HTTP" se entenderán los unos a los otros y serán capaces de intercambiar recursos (o cuando el recurso no exista, un servidor aún puede responder y dejártelo saber).


Una Solicitud y Respuesta Sin Alterar

Un explorador web sabe cómo enviar una solicitud HTTP abriendo una conexión de red a una máquina servidor y enviando un mensaje HTTP como texto. No hay nada mágico sobre la solicitud- es solamente una orden en texto ASCII plano y formateado de acuerdo a la especificación HTTP. Cualquier aplicación que pueda enviar datos sobre la red puede hacer una solicitud HTTP. Incluso puedes realizar una solicitud manual utilizando una aplicación como Telnet desde la línea de comandos. Una sesión Telnet normal se conecta a través del puerto 23, pero como hemos aprendido en el primer capítulo el puerto por defecto para HTTP es el puerto 80.

La siguiente imagen es una captura de pantalla de una sesión Telnet que se conecta a odetocode.com en el puerto 80, realiza una solicitud HTTP y recibe una respuesta HTTP.

Figure 2: Making an HTTP request
Realizando una solicitud HTTP.

La sesión Telnet empieza escribiendo:

Toma en cuenta que el cliente Telnet no está instalado por defecto en Windows 7, Windows Server 2008 R2, Windows Vista o Windows Server 2008. Puedes instalar el cliente siguiendo el procedimiento indicado en: http://technet.microsoft.com/en-us/library/cc771275(v=ws.10).aspx.

Este comando le indica al sistema operativo que ejecute la aplicación de Telnet, y le indica a la aplicación Telnet que se conecte a www.odetocode.com en el puerto 80.

Una vez Telnet se conecta, podemos escribir un mensaje de solicitud HTTP. La primer línea es creada escribiendo el siguiente texto y luego presionando Enter:

Esta información le indicará al servidor que queremos obtener el recurso localizado en "/" (por ejemplo, el recurso raíz o la página principal), y estaremos utilizando las características de HTTP 1.1. La siguiente línea que escribimos es:

Esta información de host es un fragmento de información requerido en un mensaje de solicitud HTTP 1.1. El motivo técnico para hacer esto es ayudar a los servidores que soportan múltiples sitios web, por ejemplo, tanto www.odetocode.com y www.odetofood.com podrían estar hospedados en el mismo servidor, y la información del host en el mensaje ayudará al servidor web a dirigir la solicitud a la aplicación web apropiada.

Después de escribir las dos líneas anteriores podemos presionar Enter dos veces para enviar el mensaje al servidor. Lo que verás después en la ventana de Telnet es la respuesta HTTP del servidor. Más adelante entraremos en más detalles, pero la respuesta indica que el recurso que queremos (la página principal por defecto de www.odetocode.com), se ha movido. Ha sido movida a la ubicación odetocode.com. Ahora es responsabilidad del cliente parsear éste mensaje de respuesta y enviar una solicitud a odetocode.com en lugar de www.odetocode.com si éste quiere obtener la página principal. Cualquier explorador web irá a la nueva ubicación automáticamente.

Estos tipos de "redirecciones" son comunes, y en éste escenario la razón es asegurarse de que todas las solicitudes para los recursos de OdeToCode vayan hacía odetocode.com y no hacía www.odetocode.com (ésta es una optimización de motores de búsqueda conocida como canonización de URL).

Ahora que hemos visto una solicitud y una respuesta HTTP cruda, indaguemos más en las piezas específicas.


Métodos de Solicitud HTTP

La palabra GET escrita en la sesión Telnet es uno de los métodos HTTP primarios. Cada mensaje de solicitud debe incluir uno de los métodos HTTP, y el método le indica al servidor lo que la solicitud quiere hacer. Un HTTP GET quiere obtener, traer y recuperar un recurso. Podrías OBTENER una imagen (GET /logo.png), o OBTENER un archivo PDF, (GET /documents/report.pdf), o cualquier otro recurso obtenible que el servidor pueda mantener. Una lista de las operaciones HTTP comunes es mostrada en la siguiente tabla.

Método Descripción
GET Recupera un recurso
PUT Actualiza un recurso
DELETE Elimina un recurso
POST Almacena un recurso
HEAD Obtiene las cabeceras para un recurso

De esos cinco métodos, solo dos son los caballos de fuerza principales de la web: GET y POST. Un explorador web crea una solicitud GET cuando quiere recuperar un recurso, como una página web, una imagen, un video o un documento. Las solicitudes GET son el tipo de solicitud más común.

Un explorador web envía una solicitud POST cuando tiene datos a enviar al servidor. Por ejemplo, haciendo click en "Agregar al Carrito" en un sitio como amazon.com enviará una solicitud POST con la información a Amazon sobre lo que queremos comprar. Las solicitudes POST son típicamente generadas por un formulario (<form>) en una página web, como el formulario que llenaste con elementos de entrada (<input>) para la información de dirección y de tarjeta de crédito.


Seguridad de GET

Hay una parte de la especificación HTTP que habla sobre la "seguridad" de los métodos HTTP. Los métodos seguros, como el nombre implica, no realiza nada "inseguro" como destruir un recurso, enviar una transacción de tarjeta de crédito o cancelar una cuenta. El método GET es uno de los métodos seguros debido a que solo debe obtener un recurso y no alterar el estado del recurso. Enviar una solicitud GET para una imagen JPG no altera la imagen, solo obtiene la imagen para su visualización. En resumen, nunca deberían de haber efectos secundarios para una solicitud GET.

Un HTTP POST no es un método seguro. Un POST normalmente altera algo en el servidor- actualiza una cuenta, entrega una orden o realiza alguna otra operación especial. Los exploradores web típicamente tratan a GET y POST de forma diferente debido a que GET es seguro y POST es inseguro. Está bien refrescar una página web obtenida por una solicitud GET- el explorador web solo rehacerá la última solicitud GET y mostrará lo que sea que el servidor envíe de vuelta. Sin embargo, si la página que estamos viendo en el explorador es la respuesta a una solicitud HTTP POST, el explorador nos alertará si intentamos refrescar la página. Quizás has visto éste tipo de mensajes de alerta en tu explorador web.

Figure 3: Refreshing a POST request
Refrescando una solicitud POST

Debido a alertas como ésta, muchas aplicaciones web siempre intentan dejar que el cliente visualice el resultado de una solicitud GET. Después de que un usuario hace click en un botón para enviar por POST información al servidor (como al enviar una orden), el servidor procesará la información y responderá con una redirección HTTP (como la redirección que vimos en la ventana de Telnet) indicándole al explorador que realice un GET a algún otro recurso. El explorador realizará la solicitud GET, el servidor responderá con un recurso "gracias por su pedido", y luego el usuario puede refrescar o imprimir la página de forma segura, tantas veces como el o ella gusten. Este un un patrón de diseño común conocido como el patrón POST/Redirect/GET.

Ahora que sabemos un poco más sobre POST y GET, hablemos sobre algunos escenarios comunes y veamos cuando utilizar los diferentes métodos.


Un escenario común de GET

Digamos que tienes una página y queremos que el usuario haga click en un enlace para ver el primer artículo en ésta serie. En éste caso un simple hiperenlace es todo lo que necesitas.

Cuando un usuario hace click en un hiperenlace en un explorador, el explorador realiza una solicitud GET a la URL especificada en el atributo href de la etiqueta de ancla. La solicitud se vería asi:


Un escenario de POST

Ahora imagina que tienes una página donde el usuario tiene que llenar información para crear una cuenta. Llenar la información requiere de etiquetas <input>, y anidamos éstas etiquetas input dentro de una etiqueta <form> y le indicamos al explorador a dónde enviar la información.

Cuando el usuario hace click en el botón de envío, el explorador se da cuenta de que el botón está dentro del formulario. El formulario le indica al explorador que el método HTTP a utilizar es POST y la ruta para POST es /account/create. La solicitud HTTP real que el explorador realiza se verá como esto.

Nota que los input del formulario están incluidos en el mensaje HTTP. Esto es muy similar a como los parámetros aparecen en una URL, como hemos visto en el artículo anterior. Queda en la aplicación web que reciba ésta solicitud parsear estos valores y crear una cuenta de usuario. La aplicación puede entonces responder en cualquier cantidad de formas, pero hay tres respuestas comunes:

  1. Responder con HTML indicándole al usuario que la cuenta ha sido creada. Haciendo esto dejará al usuario ver el resultado de la petición POST, lo cual puede llevar a problemas si el o ella refresca la página- podría intentar registrarse una segunda vez!
  2. Responder con una instrucción de redirección como la que vimos anteriormente para dejar al explorador realizar una solicitud GET segura para una página que le indique al usuario que la cuenta ha sido creada.
  3. Responder con un error, o redirigir a una página de error Veremos los escenarios de error un poco más adelante en éste libro.

Los Formularios y las Solicitudes GET

Un tercer escenario es un escenario de búsqueda. En un escenario de búsqueda necesitas una entrada (<input>) para que el usuario ingrese un término de búsqueda. Podría verse como lo siguiente.

Nota que el método de éste formulario es GET, no POST. Esto es porque una búsqueda es una operación de recuperación segura, a diferencia de crear una cuenta o reservar un vuelo a Bélgica. El explorador colectará los inputs en el formulario en realizará una solicitud GET al servidor:

Nota que en lugar de poner los valores de los input en el cuerpo del mensaje, los inputs van en la porción del query string de la URL. El explorador está enviando una solicitud GET para /search?term=love. Debido a que el término de búsqueda está en la URL, el usuario puede marcar la URL o copiar el enlace y enviarlo en un correo. El usuario puede también refrescar la página tantas veces como el o ella gusten, nuevamente porque la operación GET para los resultados de la búsqueda es una operación segura que no destruirá o cambiará información.


Una Palabra sobre los Métodos y Recursos

Hemos hablado bastante sobre los recursos como recursos físicos en el sistema de archivos del servidor. Frecuentemente, los recursos como archivos PDF, archivos de video, archivos de imágenes, y archivos de script existen como archivos físicos en el servidor. Sin embargo, las URLs apuntadoras dentro de muchas aplicaciones web modernas no apuntan realmente a archivos. Las tecnologías como ASP.NET y Ruby on Rails interceptarán la solicitudes para un recurso y responderán lo que consideren conveniente. Podrían leer un archivo de una base de datos y regresar el contenido de la respuesta HTTP para hacerlo parecer como si el recurso existiera realmente en el servidor.

Un buen ejemplo es el ejemplo de POST que utilizamos anteriormente que resultó en una solicitud a /account/create. Es posible que no exista ningún archivo llamado "create" en un directorio "account". En su lugar, algo en el servidor web captura la solicitud, lee y valida la información del usuario y crea un registro en la base de datos. El recurso /account/create es virtual y no existe. Sin embargo, entre más pienses en un recurso virtual como un recurso real, mejor será la arquitectura de tu aplicación y el diseño se adherirá a las fortalezas de HTTP.


Cabeceras de Solicitud HTTP

Hasta ahora hemos visto las solicitudes HTTP crudas y hemos hablado sobre dos métodos HTTP populares- GET y POST. Pero, como la salida demostrada por Telnet, existe más en un mensaje de solicitud HTTP que solo el método HTTP. Un mensaje de solicitud HTTP completo consiste de las siguientes partes:

El mensaje es siempre texto ASCII, y en la línea de inicio siempre contiene el método, la URL y la versión de HTTP (más comúnmente 1.1, el cual ha existido desde 1999). La última sección, la sección del cuerpo puede contener datos como los parámetros de creación de cuenta que vimos anteriormente. Cuando cargamos un archivo, la sección del cuerpo puede ser bastante extensa.

La sección del medio, la sección donde vimos Host:odetocode.com, contiene una o más cabeceras HTTP (recuerda, en HTTP 1.1 host es una cabecera obligatoria). Las cabeceras contienen información útil que puede ayudar a un servidor a procesar una solicitud. Por ejemplo, en el último artículo hablamos sobre las representaciones del recurso y como el cliente y el servidor pueden negociar sobre la mejor representación de un recurso (negociación de contenido). Si el cliente quiere ver un recurso en francés, por ejemplo, puede incluir una entrada de cabecera (la cabecera Accept-Language) solicitando el contenido en francés.

Existen numerosas cabeceras definidas por la especificación HTTP. Algunas de las cabeceras son cabeceras genéricas que pueden aparecer en ya sea en los mensajes de solicitud o respuesta. Un ejemplo es la cabecera Date. El cliente o el servidor puede incluir una cabecera Date cuando crea el mensaje.

Exceptuando la cabecera host, todo es opcional, pero cuando una cabecera aparece debe regirse por los estándares. Por ejemplo, la especificación HTTP indica que el valor de una cabecera de fecha debe estar en el formato RFC822 para las fechas.

Algunas de las cabeceras de solicitud más populares aparecen en la siguiente tabla.

Cabecera Descripción
Referer Cuando el usuario hace click en un enlace, el cliente puede enviar la URL de la página de referencia en esa cabecera.
User-Agent Información sobre el agente de usuario (software) que hace la solicitud. Muchas aplicaciones utilizan la información en ésta cabecera, cuando está presente, para descubrir que explorador está haciendo la solicitud (Internet Explorer 6 o Internet Explorer 9 o Chrome, etc).
Accept Describe los tipos de medio (media-types) que el agente de usuario está dispuesto a aceptar. Esta cabecera es utilizada para la negociación de contenido.
Accept-Language Describe el idioma que el agente de usuario prefiere.
Cookie Contiene información sobre las cookies, las cuales veremos en un capitulo posterior. La información de cookies generalmente ayuda a un servidor a dar seguimiento o identificar a un usuario.
If-Modified-Since Esta contendrá una fecha de cuando el agente de usuario obtuvo (y almacenó en caché) el recurso. El servidor solo tiene que enviar de vuelta el recurso completo si ha sido modificado desde esa fecha.

Una solicitud HTTP completa quedaría como la siguiente.

Cómo puedes ver, algunas cabeceras contienen múltiples valores, como la cabecera Accept. La cabecera Accept está listando los tipos MIME que le gustaría ver, incluyendo HTML, XHTML, XML y finalmente */* (lo cual quiere decir que lo mejor sería HTML, pero puedes enviarme lo que sea (*/*) y yo intentaré descifrarlo).

También nota la aparición de "q" en algunas de las cabeceras. El valor q es siempre un número de 0 a 1 y representa el valor de calidad o "grado relativo de preferencia" para un valor particular. El valor por defecto es 1.0, y números más altos indican una preferencia mayor.


La Respuesta

Una respuesta HTTP tiene una estructura similar a una solicitud HTTP. Las secciones de la respuesta son:

La respuesta HTTP completa para la última solicitud completa que mostramos se vería como esto (con la mayor parte del HTML omitido por brevedad).

La línea de apertura de una solicitud empieza con la versión HTTP y luego el sumamente-importante código de estado y el motivo.


Códigos de Estado de la Respuesta

El código de estado es un número definido por la especificación HTTP y todos los números recaen en una de cinco categorías.

Rango Categoría
100-199 Informativo
200-299 Exitoso
300-399 Redirección
400-499 Error del Cliente
500-599 Error de Servidor

Aunque no detallaremos todos los códigos de estado HTTP posibles, la siguiente tabla detallará los códigos mas comunes.

Código Motivo Descripción
200 OK El código de estado que todos quieren ver. Un código 200 en la respuesta quiere decir que ¡todo funcionó!
301 Movido Permanentemente El recurso ha sido movido a la URL especificada en la cabecera Location y el cliente nunca necesita volver a revisar ésta URL otra vez.

Vimos un ejemplo de esto anteriormente cuando utilizamos Telnet y el servidor nos redirijo de www.odetocode.com a odetocode.com para proporcionarles a los motores de búsqueda una URL canónica.
302 Movido Temporalmente El recurso ha sido movido a la URL especificada en la cabecera Location. En el futuro, el cliente puede aún solicitar la URL porque es un movimiento temporal.

Éste tipo de respuesta es típicamente utilizada despues de una operación POST para mover a un cliente a un recurso que pueda obtener con GET (el patrón POST/Redirect/GET del que hablamos con anterioridad).
304 No Modificado Éste es el servidor indicándole al cliente que el recurso no ha sido cambiado desde la última vez que cliente obtuvo el recurso, así que puede utilizar una copia localmente cacheada.
400 Solicitud Errónea El servidor no pudo entender la solicitud. La solicitud probablemente utilizó una sintáxis incorrecta.
403 Prohibido El servidor rechazó el acceso al recurso.
404 No encontrado Un código popular que indica que el recurso no fue encontrado.
500 Error interno de Servidor El servidor encontró un error al procesar la solicitud. Comúnmente ocurre debido a errores de programación en una aplicación web.
503 Servicio no disponible El servidor no atenderá la petición en éste momento. Éste código de estado puede aparecer cuando un servidor está rechazando las solicitudes porque está bajo una carga pesada.

Los códigos de estado de respuesta son una parte increíblemente importante del mensaje HTTP porque le indican al cliente que ocurrió (o en caso de redirección, a dónde ir después).


Códigos de Estado HTTP Versus tu Aplicación

Recuerda que el código de estado HTTP es un código para indicar que está ocurriendo a nivel de HTTP. Éste no necesariamente refleja que ocurrió en tu aplicación. Por ejemplo, imagina a un usuario enviando un formulario de registro al servidor, pero que no llena el campo de apellido. Si tu aplicación requiere un apellido ésta fallará al crear una cuenta para el usuario. Ésto no quiere decir que tengas que regresar un código HTTP de error indicando la falla. Probablemente quieras que ocurra lo contrario, quieres regresar exitosamente algún contenido al cliente con un código de estado 200 (OK). El contenido le indicará  al usuario que el apellido no fue proporcionado. Desde la perspectiva de la aplicación, la solicitud fue una falla, pero desde la perspectiva de HTTP, la solicitud fue exitosamente procesada. Esto es normal en las aplicaciones web.


Cabeceras de Respuesta

Una respuesta incluye información de cabecera que proporciona al cliente metadatos que puede utilizar para procesar la respuesta. Por ejemplo, el tipo de contenido será especificado como un tipo MIME como hablamos en el último artículo. En la siguiente respuesta podemos ver que el tipo de contenido es HTML y el conjunto de caracteres utilizado para codificar el tipo es UTF-8. Las cabeceras también pueden contener información sobre el servidor, como el nombre del software y la versión.

Las cabeceras de respuesta que aparecen, frecuentemente dependerán del tipo de respuesta. Por ejemplo, una respuesta de redirección necesita incluir una cabecera Location que le indique al cliente a dónde ir después.

Existen numerosas cabeceras dedicadas a almacenamiento en caché y a optimizaciones de rendimiento. ETag, Expires, y Last-Modified proporcionan información sobre las posibilidades de almacenamiento en caché de la respuesta. Un ETag es un identificador que cambiará cuando el recurso subyacente cambie, así que la comparación del ETag es una forma eficiente de saber si algo necesita ser refrescado. Una cabecera Expires le indica al cliente por cuanto tiempo almacenar el caché un recurso particular. Regresaremos y veremos el almacenamiento en caché en mayor detalle más adelante.


¿Dónde estamos?

En éste capítulo hemos aprendido que los mensajes HTTP siempre vienen en pares. Primero hay una solicitud, y luego hay una respuesta. La información en éstos mensajes está completamente en texto legible, y existen bastantes herramientas que puedes utilizar para inspeccionar las solicitudes HTTP que están realizándose en tu máquina. Fiddler es una de dichas herramientas si estás utilizando Windows (http://fiddler2.com). Es sencillo de utilizar y puedes ver las solicitudes HTTP crudas siendo realizadas, incluyendo todas las cabeceras.

Los mensajes son todos para asegurarnos de que ambas partes en una transacción entienden lo que están recibiendo. La primera línea del mensaje HTTP siempre es explícita sobre su intención. En un mensaje de solicitud, la URL y el método HTTP aparecen al principio para identificar que debería de pasar para un recurso particular. En una respuesta, el código de estado indicará como la solicitud fue procesada. También tenemos cabeceras moviendose en ambas direcciones que proporcionan más información sobre la solicitud y respuesta. En el siguiente capítulo aprenderemos un poco más sobre cómo éstos mensajes viajan a través de la red.

¡Sé el primero en conocer las nuevas traducciones–sigue @tutsplus_es en Twitter!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.