La mayoría de las aplicaciones web utilizan un modelo de solicitud/respuesta para obtener una página HTML completa del servidor. A menudo es un proceso repetitivo de hacer clic en un botón, esperar a que el servidor responda, hacer clic en otro botón y luego esperar nuevamente. Con Ajax y el objeto XMLHttpRequest, puede utilizar un modelo de solicitud/respuesta que no requiere que el usuario espere una respuesta del servidor. En este artículo, Brett McLaughlin explica cómo crear instancias XMLHttpRequest que puedan adaptarse a diferentes navegadores, establecer y enviar solicitudes y responder al servidor.
En el artículo anterior de esta serie (consulte Recursos para obtener un enlace), presentamos las aplicaciones Ajax y examinamos los conceptos básicos que impulsan las aplicaciones Ajax. En el centro de esto hay muchas tecnologías que probablemente ya conozca: JavaScript, HTML y XHTML, un poco de HTML dinámico y DOM (Document Object Model). Este artículo se centrará en un punto y se centrará en detalles específicos de Ajax.
En este artículo, comenzarás a entrar en contacto con los objetos y métodos de programación más básicos y fundamentales relacionados con Ajax: el objeto XMLHttpRequest. Este objeto es en realidad solo un hilo común que abarca todas las aplicaciones Ajax y, como es de esperar, necesita comprender a fondo este objeto para desarrollar todo su potencial de programación. De hecho, a veces encontrará que para usar XMLHttpRequest correctamente, obviamente no puede usar XMLHttpRequest. ¿Qué está pasando?
Web 2.0 de un vistazo
Antes de profundizar en el código, echemos un vistazo a las perspectivas recientes: es importante tener muy claro el concepto de Web 2.0. Cuando escuche el término Web 2.0, primero debe preguntarse "¿Qué es la Web 1.0?" Aunque es raro escuchar a la gente mencionar la Web 1.0, de hecho se refiere a la Web tradicional con un modelo de solicitud y respuesta completamente diferente. Por ejemplo, vaya al sitio web Amazon.com y haga clic en un botón o ingrese un término de búsqueda. Se envía una solicitud al servidor y la respuesta se devuelve al navegador. La solicitud no es sólo una lista de libros y títulos, sino otra página HTML completa. Por lo tanto, es posible que observe parpadeos o vibraciones cuando el navegador web vuelva a dibujar la página con el nuevo HTML. De hecho, las solicitudes y respuestas son claramente visibles con cada página nueva que ve.
La Web 2.0 elimina (en gran medida) esta interacción visible de ida y vuelta. Por ejemplo, visite un sitio como Google Maps o Flickr (consulte Recursos para obtener enlaces a estos sitios Web 2.0 y habilitados para Ajax). En Google Maps, por ejemplo, puedes arrastrar el mapa para acercarlo y alejarlo con un mínimo de rediseño. Por supuesto, todavía hay solicitudes y respuestas, pero están ocultas detrás de escena. Como usuario, la experiencia es más cómoda y se parece mucho a una aplicación de escritorio. Este nuevo sentimiento y paradigma es lo que se obtiene cuando alguien menciona la Web 2.0.
La preocupación es hacer posibles estas nuevas interacciones. Obviamente, aún necesita realizar solicitudes y recibir respuestas, pero es el rediseño del HTML para cada interacción de solicitud/respuesta lo que crea la sensación de interacciones web lentas y torpes. Por lo tanto, está claro que necesitamos una forma de enviar solicitudes y recibir respuestas que solo contengan los datos requeridos en lugar de toda la página HTML. El único momento en el que necesita obtener la nueva página HTML completa es cuando desea que el usuario vea la nueva página.
Pero la mayoría de las interacciones agregan detalles a páginas existentes, modifican el texto principal o sobrescriben los datos originales. En estos casos, los métodos Ajax y Web 2.0 permiten enviar y recibir datos sin actualizar toda la página HTML. Para aquellos que pasan mucho tiempo en línea, esta capacidad puede hacer que sus aplicaciones se sientan más rápidas y con mayor capacidad de respuesta, haciendo que vuelvan a su sitio de vez en cuando.
Introducción a XMLHttpRequest
Para realizar realmente este magnífico milagro, debe estar muy familiarizado con un objeto JavaScript, a saber, XMLHttpRequest. Este pequeño objeto ha estado presente en varios navegadores durante algún tiempo y está en el corazón de la Web 2.0, Ajax y muchas otras cosas que cubriré en esta columna durante los próximos meses. Para brindarle una descripción general rápida, estos son solo algunos de los métodos y propiedades que se utilizarán en este objeto.
·open(): Establece una nueva petición al servidor.
·send(): envía una solicitud al servidor.
·abort(): Cancela la solicitud actual.
·readyState: Proporciona el estado listo del HTML actual.
·responseText: El texto de respuesta de la solicitud devuelto por el servidor.
No se preocupe si no los conoce (o ninguno de ellos), cubriremos cada método y propiedad en los próximos artículos. Lo que debes saber ahora es exactamente qué hacer con XMLHttpRequest. Tenga en cuenta que estos métodos y propiedades están relacionados con el envío de solicitudes y el procesamiento de respuestas. De hecho, si observa todos los métodos y propiedades de XMLHttpRequest, encontrará que todos se relacionan con un modelo de solicitud/respuesta muy simple. Obviamente, no vamos a encontrar un objeto GUI particularmente nuevo o alguna forma súper arcana de crear interacción con el usuario, usaremos solicitudes y respuestas muy simples. Puede que no parezca mucho, pero utilizar bien este objeto puede revolucionar tu aplicación.
La novedad simple
primero requiere crear una nueva variable y asignarle una instancia de objeto XMLHttpRequest. Esto es tan simple como usar la nueva palabra clave en el nombre del objeto en JavaScript, como se muestra en el Listado 1.
Listado 1. Creación de un nuevo objeto XMLHttpRequest
<script language="javascript" type="text/javascript">
solicitud var = nueva XMLHttpRequest();
</script>
¿No es difícil? Recuerde, JavaScript no requiere que especifique tipos de variables, por lo que no necesita hacer lo que hace en el Listado 2 (que podría hacer en el lenguaje Java).
Listado 2. Pseudocódigo Java para crear una
solicitud XMLHttpRequestXMLHttpRequest = new XMLHttpRequest();
Entonces, en JavaScript creas una variable usando var, le das un nombre (como "solicitud") y luego le asignas una nueva instancia de XMLHttpRequest. Luego, el objeto se puede utilizar en funciones.
Manejo de errores
Todo tipo de cosas pueden salir mal, y el código anterior no proporciona ningún manejo de errores. Un mejor enfoque es crear el objeto y salir con gracia si algo sale mal. Por ejemplo, los navegadores más antiguos (lo creas o no, todavía hay personas que usan versiones anteriores de Netscape Navigator) no admiten XMLHttpRequest y debes informar a estos usuarios que algo anda mal. El Listado 3 muestra cómo crear este objeto para emitir una advertencia de JavaScript cuando ocurre un problema.
Listado 3. Creación de una XMLHttpRequest con capacidades de manejo de errores
<script idioma="javascript" tipo="texto/javascript">
solicitud var = falso;
intentar {
solicitud = nueva XMLHttpRequest();
} captura (falló) {
solicitud = falso;
}
si (!solicitud)
alert("¡Error al inicializar XMLHttpRequest!");
</script>
Asegúrese de comprender estos pasos:
1. Cree una nueva solicitud de variable y asígnele un valor falso. Falso se utilizará como condición de juicio más adelante, lo que significa que el objeto XMLHttpRequest aún no se ha creado.
2. Agregue el bloque try/catch:
1) Intente crear un objeto XMLHttpRequest.
2) Si falla (catch (falló)), se garantiza que el valor de la solicitud sigue siendo falso.
3. Compruebe si la solicitud sigue siendo falsa (no será falsa si todo es normal).
4. Si ocurre un problema (la solicitud es falsa), use la advertencia de JavaScript para notificar al usuario que ha ocurrido un problema.
El código es muy simple y, a la mayoría de los desarrolladores web y de JavaScript, les llevará más tiempo entenderlo realmente que leerlo y escribirlo. Ahora tiene un fragmento de código de creación de objetos XMLHttpRequest que está verificado para detectar errores y puede indicarle qué salió mal.
Todo parece ir biencon Microsoft
, al menos hasta que pruebas el código con Internet Explorer. Si experimenta así, verá la mala situación que se muestra en la Figura 1.
Figura 1. Error de informe de Internet Explorer
Es evidente que algo anda mal, e Internet Explorer no es un navegador obsoleto, ya que lo utiliza el 70% del mundo. En otras palabras, si no es compatible con Microsoft e Internet Explorer, ¡no será popular en el mundo Web! Por eso debemos adoptar un enfoque diferente con los navegadores de Microsoft.
Se verificó que Microsoft soporta Ajax, pero su versión XMLHttpRequest tiene un nombre diferente. De hecho, lo llama de varias maneras diferentes. Si utiliza versiones más recientes de Internet Explorer, deberá utilizar el objeto Msxml2.XMLHTTP, mientras que las versiones anteriores de Internet Explorer utilizan Microsoft.XMLHTTP. Necesitamos admitir ambos tipos de objetos (así como navegadores que no sean de Microsoft). Eche un vistazo al Listado 4, que se basa en el código anterior y agrega soporte para Microsoft.
¿Está Microsoft involucrado?
Se ha escrito mucho sobre el creciente interés y participación de Ajax y Microsoft en esta área. De hecho, se dice que la última versión de Internet Explorer de Microsoft (la versión 7.0, que saldrá en la segunda mitad de 2006) comenzará a soportar XMLHttpRequest directamente, permitiéndole usar la nueva palabra clave en lugar de todo el código de creación Msxml2.XMLHTTP. Pero no se entusiasme demasiado, los navegadores más antiguos aún necesitan ser compatibles, por lo que el código entre navegadores no desaparecerá pronto.
Listado 4. Agregar soporte para navegadores de Microsoft
<script idioma="javascript" tipo="texto/javascript">
solicitud var = falso;
intentar {
solicitud = nueva XMLHttpRequest();
} captura (prueba microsoft) {
intentar {
solicitud = nuevo ActiveXObject("Msxml2.XMLHTTP");
} atrapar (otro microsoft) {
intentar {
solicitud = nuevo ActiveXObject("Microsoft.XMLHTTP");
} captura (falló) {
solicitud = falso;
}
}
}
si (!solicitud)
alert("¡Error al inicializar XMLHttpRequest!");
</script>
Es fácil confundirse con estas llaves, por lo que cada paso se presenta a continuación:
1. Cree una nueva solicitud de variable y asígnele un valor falso. Utilice falso como condición de juicio, lo que significa que el objeto XMLHttpRequest aún no se ha creado.
2. Agregue el bloque try/catch:
1) Intente crear un objeto XMLHttpRequest.
2) Si falla (captura (trymicrosoft)):
1>Intente utilizar una versión más reciente del navegador de Microsoft para crear un objeto compatible con Microsoft (Msxml2.XMLHTTP).
2> Si falla (catch (othermicrosoft)), intente crear un objeto compatible con Microsoft (Microsoft.XMLHTTP) utilizando una versión anterior del navegador de Microsoft.
2) Si falla (catch (falló)), se garantiza que el valor de la solicitud sigue siendo falso.
3. Compruebe si la solicitud sigue siendo falsa (no será falsa si todo va bien).
4. Si ocurre un problema (la solicitud es falsa), use la advertencia de JavaScript para notificar al usuario que ha ocurrido un problema.
Después de modificar el código de esta manera y probarlo usando Internet Explorer, deberías ver el formulario que se ha creado (sin mensaje de error). Los resultados de mi experimento se muestran en la Figura 2.
Figura 2. Internet Explorer funcionando normalmente
Estático versus dinámico
Eche otro vistazo a los Listados 1, 3 y 4. Observe que todo este código está anidado directamente dentro de la etiqueta script. El código JavaScript como este que no se coloca en un método o cuerpo de función se llama JavaScript estático. Esto significa que el código se ejecuta en algún momento antes de que la página se muestre al usuario. (Aunque la especificación no sabe con total precisión qué efecto tendrá este código en el navegador cuando se ejecute, se garantiza que se ejecutará antes de que el usuario pueda interactuar con la página). Esta es también la forma general en que la mayoría Los programadores de Ajax crean objetos XMLHttpRequest.
Dicho esto, también puedes poner este código en un método como el Listado 5.
Listado 5. Mover el código de creación XMLHttpRequest a un método
<script language="javascript" type="text/javascript">
var solicitud;
función createRequest() {
intentar {
solicitud = nueva XMLHttpRequest();
} captura (prueba microsoft) {
intentar {
solicitud = nuevo ActiveXObject("Msxml2.XMLHTTP");
} atrapar (otro microsoft) {
intentar {
solicitud = nuevo ActiveXObject("Microsoft.XMLHTTP");
} captura (falló) {
solicitud = falso;
}
}
}
si (!solicitud)
alert("¡Error al inicializar XMLHttpRequest!");
}
</script>
Si escribe su código de esta manera, debe llamar a este método antes de manejar Ajax. Por lo tanto, también se necesita código como el Listado 6.
Listado 6. Crear método usando XMLHttpRequest
<script language="javascript" type="text/javascript">
var solicitud;
función createRequest() {
intentar {
solicitud = nueva XMLHttpRequest();
} captura (prueba microsoft) {
intentar {
solicitud = nuevo ActiveXObject("Msxml2.XMLHTTP");
} atrapar (otro microsoft) {
intentar {
solicitud = nuevo ActiveXObject("Microsoft.XMLHTTP");
} captura (falló) {
solicitud = falso;
}
}
}
si (!solicitud)
alert("¡Error al inicializar XMLHttpRequest!");
}
función obtenerInfoCliente() {
crearSolicitud();
//Hacer algo con la variable de solicitud
}
</script>
El único problema con este código es que retrasa la notificación de errores, razón por la cual la mayoría de los programadores de Ajax no utilizan este enfoque. Supongamos que tiene un formulario complejo con 10 o 15 campos, cuadros de selección, etc., y desea activar algún código Ajax cuando el usuario ingresa texto en el campo 14 (de arriba a abajo en el orden del formulario). En este punto, ejecutar getCustomerInfo() intenta crear un objeto XMLHttpRequest, pero (en este caso) falla. Luego se muestra al usuario una advertencia que le indica claramente que no puede utilizar la aplicación. ¡Pero los usuarios ya dedican mucho tiempo a introducir datos en los formularios! Esto es muy molesto y, obviamente, ser molesto no atraerá a los usuarios a regresar a su sitio.
Si utiliza JavaScript estático, los usuarios verán mensajes de error muy rápidamente cuando hagan clic en la página. Eso también es molesto, ¿no? El usuario puede creer erróneamente que su aplicación web no puede ejecutarse en su navegador. Pero ciertamente es mejor que pasar 10 minutos ingresando información para luego mostrar el mismo error. Por lo tanto, recomiendo escribir código estático para permitir a los usuarios detectar problemas lo antes posible.
Después deenviar una solicitud con XMLHttpRequest
y obtener el objeto de solicitud, puede ingresar al ciclo de solicitud/respuesta. Recuerde, el único propósito de XMLHttpRequest es permitirle enviar solicitudes y recibir respuestas. Todo lo demás es trabajo de JavaScript, CSS u otro código de la página: cambiar la interfaz de usuario, cambiar imágenes, interpretar los datos devueltos por el servidor. Después de preparar XMLHttpRequest, puede enviar la solicitud al servidor.
Bienvenido a Sandbox
Ajax utiliza un modelo de seguridad sandbox. Por lo tanto, el código Ajax (específicamente, el objeto XMLHttpRequest) sólo puede enviar solicitudes al mismo dominio en el que se encuentra. Cubriremos más sobre seguridad y Ajax en un artículo futuro, pero por ahora solo sepa que el código que se ejecuta en la máquina local solo puede realizar solicitudes a scripts del lado del servidor en la máquina local. Si desea que el código Ajax se ejecute en www.breakneckpizza.com , la solicitud debe enviarse desde un script que se ejecute en www.breakneckpizza.com .
Para configurar la URL del servidor,
primero debe determinar la URL del servidor conectado. Este no es un requisito especial para Ajax, pero aún así es necesario establecer la conexión, y ahora obviamente deberías saber cómo construir una URL. En la mayoría de las aplicaciones, esta URL se construye a partir de una combinación de algunos datos estáticos y datos de un formulario que procesa el usuario. Por ejemplo, el código JavaScript del Listado 7 obtiene el valor del campo del número de teléfono y lo utiliza para construir una URL.
Listado 7. Creando la URL de solicitud
<script idioma="javascript" tipo="texto/javascript">
solicitud var = falso;
intentar {
solicitud = nueva XMLHttpRequest();
} captura (prueba microsoft) {
intentar {
solicitud = nuevo ActiveXObject("Msxml2.XMLHTTP");
} atrapar (otro microsoft) {
intentar {
solicitud = nuevo ActiveXObject("Microsoft.XMLHTTP");
} captura (falló) {
solicitud = falso;
}
}
}
si (!solicitud)
alert("¡Error al inicializar XMLHttpRequest!");
función getCustomerInfo() {
var teléfono = document.getElementById("teléfono").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(teléfono);
}
</script>
Nada difícil de entender aquí. Primero, el código crea una nueva variable teléfono y le asigna el valor del campo del formulario con el ID "teléfono". El Listado 8 muestra el XHTML para este formulario, donde puede ver el campo del teléfono y su atributo de identificación.
Listado 8. Forma de pizza Break Neck
<cuerpo>
<p><img src="breakneck-logo_4c.gif" alt="Pizza para romper el cuello" /></p>
<formulario acción="POST">
<p>Ingrese su número de teléfono:
<tipo de entrada="texto" tamaño="14" nombre="teléfono" id="teléfono"
onChange="getClienteInfo();"
</p>
<p>Tu pedido será entregado</p>
<div id="dirección"></div>
<p>Escriba su pedido aquí:</p>
<p><textarea name="orden" filas="6" cols="50" id="orden"></textarea></p>
<p><input type="enviar" valor="Pedir pizza" id="enviar" /></p>
</formulario>
</body>
Tenga en cuenta también que cuando el usuario ingresa un número de teléfono o cambia el número de teléfono, se activa el método getCustomerInfo() que se muestra en el Listado 8. Este método obtiene el número de teléfono y construye una cadena de URL almacenada en la variable URL. Recuerde, debido a que el código Ajax está protegido y solo puede conectarse al mismo dominio, en realidad no es necesario un nombre de dominio en la URL. El script en este ejemplo se llama /cgi-local/lookupCustomer.php. Finalmente, el número de teléfono se agrega al script como parámetro GET: "teléfono=" + escape(teléfono).
Si no ha visto el método escape() antes, se utiliza para escapar de cualquier carácter que no se pueda enviar correctamente en texto sin cifrar. Por ejemplo, los espacios en los números de teléfono se convertirán en los caracteres %20, lo que permitirá que estos caracteres se pasen en la URL.
Puede agregar tantos parámetros como sea necesario. Por ejemplo, si necesita agregar otro parámetro, simplemente agréguelo a la URL y sepárelo con el carácter comercial (&) [el primer parámetro está separado del nombre del script con un signo de interrogación (?)].
Abra la solicitud
Una vez que tenga la URL para conectarse, puede configurar la solicitud. Esto se puede lograr utilizando el método open() del objeto XMLHttpRequest. Este método tiene cinco parámetros:
tipo de solicitud: el tipo de solicitud a enviar. Los valores típicos son GET o POST, pero también se puede enviar una solicitud HEAD.
url: la URL a la que conectarse.
asynch: verdadero si desea utilizar una conexión asincrónica, falso en caso contrario. Este parámetro es opcional y su valor predeterminado es verdadero.
nombre de usuario: si se requiere autenticación, puede especificar el nombre de usuario aquí. Este parámetro opcional no tiene valor predeterminado. contraseña: si se requiere autenticación, puede especificar una contraseña aquí. Este parámetro opcional no tiene valor predeterminado.
¿Se abre open()?
Los desarrolladores de Internet no se ponen de acuerdo sobre qué hace exactamente el método open(). Pero en realidad no abre una solicitud. Si monitorea la red y la transferencia de datos entre una página XHTML/Ajax y su script de conexión, no verá ninguna comunicación cuando se llame al método open(). No está claro por qué se eligió este nombre, pero claramente no es una buena elección.
Normalmente se utilizan los primeros tres parámetros. De hecho, incluso si se requiere una conexión asíncrona, el tercer parámetro debe especificarse como "verdadero". Este es el valor predeterminado, pero es más fácil de entender insistir en especificar explícitamente si la solicitud es asíncrona o síncrona.
Combinarlos generalmente da como resultado una línea de código como la que se muestra en el Listado 9.
Listado 9.
Función de solicitud abierta getCustomerInfo() {
var teléfono = document.getElementById("teléfono").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(teléfono);
request.open("OBTENER", url, verdadero);
}
Una vez que hayas configurado la URL, el resto es fácil. Para la mayoría de las solicitudes, GET es suficiente (verá cuándo se requiere POST en un artículo posterior), más la URL, y eso es todo lo que necesita para usar el método open().
Desafiando la asincronicidad
En el próximo artículo de esta serie, dedicaré mucho tiempo a escribir y usar código asincrónico, pero debes entender por qué el último parámetro de open() es tan importante. En un modelo general de solicitud/respuesta, como la Web 1.0, el cliente (un navegador o código que se ejecuta en la máquina local) realiza una solicitud al servidor. La solicitud es sincrónica, es decir, el cliente espera una respuesta del servidor. Cuando el cliente esté esperando, se le notificará de la espera al menos de alguna forma:
· Reloj de arena (especialmente en Windows).
·Bola giratoria (normalmente en máquinas Mac).
·La aplicación básicamente se congela y luego de un tiempo el cursor cambia.
Ésta es exactamente la razón por la que las aplicaciones web parecen torpes o lentas: una falta de verdadera interactividad. Cuando se presiona el botón, la aplicación efectivamente queda inutilizable hasta que se responde a la solicitud que acaba de activarse. Si la solicitud requiere mucho procesamiento del servidor, el tiempo de espera puede ser largo (al menos en este mundo multiprocesador, DSL sin espera).
Las solicitudes asincrónicas no esperan una respuesta del servidor. La aplicación continúa ejecutándose después de enviar la solicitud. Los usuarios aún pueden ingresar datos en el formulario web o incluso salir del formulario. No hay bolas que giran ni relojes de arena, y la aplicación no se congela notablemente. El servidor responde silenciosamente a la solicitud y, cuando finaliza, le dice al solicitante original que el trabajo ha finalizado (verá qué pronto). El resultado es una aplicación que se siente menos lenta y con mayor capacidad de respuesta, interactiva y mucho más rápida. Esta es sólo una parte de la Web 2.0, pero es una parte importante. Todos los viejos componentes GUI y paradigmas de diseño web no pueden superar el modelo de solicitud/respuesta lento y sincrónico.
Envío de solicitudes
Una vez configurado con open(), puede enviar solicitudes. Afortunadamente, el método para enviar solicitudes tiene un nombre más apropiado que open(): es send().
send() tiene solo un parámetro, que es el contenido a enviar. Pero antes de considerar este método, recuerde que ya ha enviado datos a través de la propia URL:
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
aunque puede usar send() para enviar datos; , Pero también es posible enviar datos a través de la propia URL. De hecho, con las solicitudes GET (que ocurren en aproximadamente el 80% de las aplicaciones Ajax típicas), es mucho más fácil enviar datos usando una URL. Si necesita enviar información segura o XML, es posible que desee considerar el uso de send() para enviar el contenido (los datos seguros y los mensajes XML se analizarán en artículos posteriores de esta serie). Si no necesita pasar datos a través de send(), simplemente pase null como parámetro de este método. Así que encontrará que esto es todo lo que necesita hacer en los ejemplos de este artículo (consulte el Listado 10).
Listado 10.
Función de envío de solicitud getCustomerInfo() {
var teléfono = document.getElementById("teléfono").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(teléfono);
request.open("OBTENER", url, verdadero);
solicitud.enviar (nulo);
}
Especificar el método de devolución de llamada
. Hay muy poco en lo que hacemos ahora que sea nuevo, revolucionario o asincrónico. Hay que admitir que la pequeña palabra clave "true" en el método open() establece una solicitud asincrónica. Pero aparte de eso, el código no es diferente a la programación con servlets Java y JSP, PHP o Perl. Entonces, ¿cuál es el mayor secreto de Ajax y Web 2.0? El secreto radica en una propiedad simple en el cambio de estado listo de XMLHttpRequest.
Asegúrese de comprender primero el flujo de este código (revise el Listado 10 si es necesario). Cree su solicitud y luego realice la solicitud. Además, debido a que la solicitud es asincrónica, el método JavaScript (getCustomerInfo() en el ejemplo) no espera al servidor. Entonces el código continuará ejecutándose, es decir, el método saldrá y el control volverá al formulario. El usuario puede seguir ingresando información y la aplicación no espera al servidor.
Esto plantea una pregunta interesante: ¿Qué sucede después de que el servidor completa la solicitud? La respuesta es que no pasa nada, ¡al menos con el código actual! Obviamente, esto no funcionará, por lo que el servidor necesita algún tipo de instrucciones sobre qué hacer después de terminar de procesar la solicitud enviada a través de XMLHttpRequest.
Funciones de referencia en JavaScript:
JavaScript es un lenguaje débilmente tipado y puedes usar variables para hacer referencia a cualquier cosa. Entonces, si declaras una función updatePage(), JavaScript también trata el nombre de la función como una variable. En otras palabras, puede hacer referencia a la función en su código utilizando el nombre de variable updatePage.
Listado 11. Establecer
la función del método de devolución de llamada getCustomerInfo() {
var teléfono = document.getElementById("teléfono").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(teléfono);
request.open("OBTENER", url, verdadero);
request.onreadystatechange = actualizarPágina;
solicitud.enviar (nulo);
}
Es importante tener en cuenta en qué parte del código se establece esta propiedad: se establece antes de llamar a send(). Esta propiedad debe configurarse antes de enviar la solicitud para que el servidor pueda verla después de responder la solicitud completa. Ahora todo lo que queda es escribir el método updatePage(), que es el tema central de la última sección de este artículo.
El servidor de procesamiento responde
a la solicitud, el usuario utiliza felizmente el formulario web (mientras el servidor procesa la solicitud) y ahora el servidor ha completado el procesamiento de la solicitud. El servidor examina el atributo onreadystatechange para determinar a qué método llamar. De lo contrario, trate su aplicación como cualquier otra aplicación, ya sea asíncrona o no. En otras palabras, no necesariamente tiene que tomar medidas especiales para escribir un método que responda al servidor, solo necesita cambiar el formulario, permitir que el usuario visite otra URL o hacer lo que el servidor de respuesta necesite. En esta sección nos centraremos en las respuestas al servidor y en una acción típica: cambiar instantáneamente parte del formulario que ve el usuario.
Devoluciones de llamada y Ajax
Ahora hemos visto cómo decirle al servidor qué hacer cuando haya terminado: establezca la propiedad onreadystatechange del objeto XMLHttpRequest con el nombre de la función que se ejecutará. De esta forma, la función se llamará automáticamente después de que el servidor haya procesado la solicitud. Tampoco hay necesidad de preocuparse por ningún parámetro de la función. Comenzamos con un método simple, que se muestra en el Listado 12.
Listado 12. Código para el método de devolución de llamada
<script idioma="javascript" tipo="texto/javascript">
solicitud var = falso;
intentar {
solicitud = nueva XMLHttpRequest();
} captura (prueba microsoft) {
intentar {
solicitud = nuevo ActiveXObject("Msxml2.XMLHTTP");
} atrapar (otro microsoft) {
intentar {
solicitud = nuevo ActiveXObject("Microsoft.XMLHTTP");
} captura (falló) {
solicitud = falso;
}
}
}
si (!solicitud)
alert("¡Error al inicializar XMLHttpRequest!");
función getCustomerInfo() {
var teléfono = document.getElementById("teléfono").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(teléfono);
request.open("OBTENER", url, verdadero);
request.onreadystatechange = actualizarPágina;
solicitud.enviar (nulo);
}
función actualizarPágina() {
alert("¡El servidor está listo!");
}
</script>
Simplemente emite algunas advertencias simples para informarle cuando el servidor ha completado su tarea. Pruebe este código en su propia página web y ábralo en un navegador (consulte el Listado 8 si desea ver el XHTML en este ejemplo). Ingrese el número de teléfono y luego salga del campo, verá una ventana emergente de advertencia (como se muestra en la Figura 3), pero haga clic en Aceptar y aparecerá nuevamente...
Figura 3. Código Ajax para la advertencia emergente
Dependiendo del navegador, es posible que vea dos, tres o incluso cuatro advertencias antes de que el formulario deje de aparecer. ¿Qué está sucediendo? Resulta que no hemos considerado el estado de preparación de HTTP, que es una parte importante del ciclo de solicitud/respuesta.
Estado HTTP listo
Como se mencionó anteriormente, el servidor busca el método que se llamará en el atributo onreadystatechange de XMLHttpRequest después de completar la solicitud. Esto es cierto, pero incompleto. De hecho, llama a este método cada vez que cambia el estado de HTTP listo. ¿Qué quiere decir esto? Primero debes comprender el estado de preparación de HTTP.
El estado HTTP listo representa el estado o condición de la solicitud. Se utiliza para determinar si la solicitud se inició, se recibió una respuesta o se completó el modelo de solicitud/respuesta. También puede ayudar a determinar si es seguro leer el texto de respuesta o los datos proporcionados por el servidor. Hay cinco estados de preparación que se deben tener en cuenta en las aplicaciones Ajax:
·0: la solicitud no se ha emitido (antes de llamar a open()).
·1: La solicitud se ha establecido pero aún no se ha enviado (antes de llamar a send()).
·2: La solicitud ha sido enviada y está siendo procesada (el encabezado del contenido generalmente se puede obtener de la respuesta).
·3: La solicitud ha sido procesada y algunos datos generalmente están disponibles en la respuesta, pero el servidor no ha completado la respuesta.
·4: La respuesta está completa y puedes acceder a la respuesta del servidor y utilizarla.
Como ocurre con la mayoría de los problemas entre navegadores, estos estados listos no se utilizan de manera consistente. Es posible que espere que el estado de preparación de la tarea pase de 0 a 1, a 2, a 3 y a 4, pero este rara vez es el caso. Algunos navegadores nunca informan 0 o 1, sino que comienzan directamente con 2, luego 3 y 4. Otros navegadores informan de todos los estados. Otros informan el estado listo 1 varias veces. Como se vio en la sección anterior, el servidor llama a updatePage() varias veces y aparece un cuadro de advertencia cada vez que se llama; ¡puede ser diferente de lo esperado!
Para la programación Ajax, el único estado que debe manejarse directamente es el estado listo 4, que indica que la respuesta del servidor está completa y que los datos de respuesta son seguros de usar. En base a esto, la primera línea del método de devolución de llamada debería verse como el Listado 13.
Listado 13. Comprobando
la función de preparación updatePage() {
si (solicitud. estado listo == 4)
alert("¡El servidor está listo!");
}
Después de la modificación, puede asegurarse de que se haya completado el procesamiento del servidor. Intente ejecutar la nueva versión del código Ajax y ahora verá el mensaje de advertencia mostrado solo una vez, como se esperaba.
Códigos de estado HTTP
Aunque el código del Listado 13 parece correcto, hay un problema: ¿qué pasa si el servidor responde a la solicitud y completa el procesamiento pero informa un error? Tenga en cuenta que el código del lado del servidor debe entender que está siendo llamado mediante Ajax, JSP, formularios HTML simples u otros tipos de código, pero solo puede informar información utilizando métodos tradicionales específicos de la Web. En el mundo web, el código HTTP puede manejar varios problemas que pueden ocurrir en la solicitud.
Por ejemplo, debe haberse encontrado con la situación en la que ingresó una solicitud de URL incorrecta y obtuvo un código de error 404, lo que significa que la página no existe. Este es solo uno de los muchos códigos de error que se pueden recibir con una solicitud HTTP (consulte el enlace en Recursos para obtener una lista completa de códigos de estado). También son comunes los 403 y 401, que indican que los datos a los que se accede están protegidos o prohibidos. En cualquier caso, estos códigos de error se obtienen de la respuesta completa. En otras palabras, el servidor cumplió con la solicitud (es decir, el estado HTTP listo es 4) pero no devolvió los datos que esperaba el cliente.
Entonces, además del estado listo, también debe verificar el estado HTTP. El código de estado esperado es 200, lo que significa que todo salió bien. Si el estado listo es 4 y el código de estado es 200, puede procesar los datos del servidor y los datos deben ser los datos solicitados (en lugar de errores u otra información problemática). Por lo tanto, también necesitamos agregar una verificación de estado en el método de devolución de llamada, como se muestra en el Listado 14.
Listado 14. Verifique
la función del código de estado HTTP updatePage() {
si (solicitud. estado listo == 4)
si (solicitud.estado == 200)
alert("¡El servidor está listo!");
}
Para agregar un manejo de errores más sólido e intentar evitar complicaciones excesivas agregando una verificación de código de estado o dos, eche un vistazo a la versión modificada de updatePage() en el Listado 15.
Listado 15. Agregue una pequeña
función de verificación de errores updatePage() {
si (solicitud. estado listo == 4)
si (solicitud.estado == 200)
alert("¡El servidor está listo!");
de lo contrario si (solicitud.status == 404)
alert("La URL de solicitud no existe");
demás
alert("Error: el código de estado es " + request.status);
}
Ahora cambie la URL en getCustomerInfo() a una URL inexistente y vea qué sucede. Deberías ver un mensaje de advertencia indicando que la URL solicitada no existe. ¡Excelente! Es difícil manejar todas las condiciones de error, pero este pequeño cambio puede cubrir el 80% de los problemas en una aplicación web típica.
Al leer el texto de respuesta,
ahora garantiza que la solicitud haya sido procesada (a través del estado listo), el servidor dio una respuesta normal (a través del código de estado), y finalmente podemos procesar los datos devueltos por el servidor. Los datos devueltos se almacenan en la propiedad ResponseText del objeto xmlhttprequest.
El contenido del texto en ResponseText, como el formato y la longitud, se deja intencionalmente vago. De esta manera, el servidor puede establecer el texto en cualquier cosa. Por ejemplo, un script podría devolver los valores separados por comas, otro usa una tubería (el personaje |) para separar los valores, y otro devuelve una cadena de texto larga. Depende del servidor decidir a dónde ir.
En el ejemplo utilizado en este artículo, el servidor devuelve el último pedido y la dirección del cliente del cliente, separados por un carácter de tubería. El orden y la dirección se usan para establecer valores de elementos en el formulario 16 muestra el código para actualizar la pantalla.
Listado 16.
Función de respuesta del servidor de manejo updatePage () {
if (request.readyState == 4) {
if (request.status == 200) {
respuesta var = request.esponsetext.split ("|");
document.getElementById ("orden"). valor = respuesta [0];
document.getElementById ("dirección"). innerhtml =
respuesta [1] .Replace (/ n/g, "");
} demás
alerta ("El estado es" + request.status);
}
}
Primero, obtenga el respuestas y divídelo de la tubería usando el método JavaScript Split (). La matriz resultante se coloca en respuesta. Se accede al primer valor en la matriz, el pedido anterior, con respuesta [0] y se establece en el valor del campo con ID "orden". La segunda respuesta de valor [1], la dirección del cliente, requiere un poco más de procesamiento. Debido a que las líneas en la dirección están separadas por separadores de línea normales (caracteres " n"), el código debe usar separadores de línea de estilo XHTML <Br />. El proceso de reemplazo se realiza utilizando la función reemplazar () y expresiones regulares. Finalmente, el texto modificado se usa como HTML interno en el formulario HTML div. El resultado es que el formulario se actualiza repentinamente con la información del cliente, como se muestra en la Figura 4.
Figura 4. Desglose el formulario del cuello después de recibir datos del cliente
Antes de terminar este artículo, me gustaría introducir otro atributo importante de XMLHTTPRequest, Respuestaxml. Esta propiedad contiene (como habrá adivinado) la respuesta XML si el servidor elige usar una respuesta XML. El procesamiento de las respuestas XML es muy diferente del procesamiento del texto ordinario, que implica el análisis, el modelo de objeto de documento (DOM) y otros problemas. XML se cubrirá más en un artículo posterior. Pero dado que Responsexml generalmente se discute junto con ResponseText, merece una mención aquí. Para muchas aplicaciones simples de Ajax, ResponseText será suficiente, pero pronto verá que XML también se puede manejar bien con aplicaciones AJAX.
Conclusión
Puede estar un poco cansado de XMLHTTPREQUEST. Pero usará este objeto una y otra vez en cada página y aplicación que escriba usando AJAX. Francamente, hay algo que decir para XMLHTTPREQUEST. El siguiente artículo introducirá cómo usar las solicitudes de publicación y recibir para establecer encabezados de contenido en las solicitudes y leer los encabezados de contenido de las respuestas del servidor, y comprenderá cómo codificar las solicitudes y procesar XML en el modelo de solicitud/respuesta.
Más tarde presentaremos las cajas de herramientas AJAX comunes. Estas cajas de herramientas en realidad ocultan muchos de los detalles descritos en este artículo, lo que facilita la programación AJAX. Es posible que se pregunte por qué necesita codificar los detalles de bajo nivel cuando hay tantas cajas de herramientas por ahí. La respuesta es que es difícil detectar problemas en una aplicación sin saber qué está haciendo la aplicación.
Así que no ignore los detalles o simplemente navegue, y si algo sale mal con esta caja de herramientas práctica y hermosa, no tendrá que rascarse la cabeza ni enviar un correo electrónico para admitir. Si comprende cómo usar XMLHTTPRequest directamente, le resultará fácil depurar y resolver los problemas más extraños. Una caja de herramientas solo es buena si deja que resuelva sus problemas.
Así que por favor familiarícese con xmlhttprequest. De hecho, si tiene un código AJAX que usa la caja de herramientas, intente reescribirla utilizando el objeto XMLHTTPREQUEST y sus propiedades y métodos. Este es un buen ejercicio para ayudarlo a comprender mejor los principios.
El próximo artículo discutirá este objeto más a fondo, explorando algunas de sus propiedades más interesantes (como Responsexml) y cómo usar solicitudes posteriores y enviar datos en diferentes formatos. Comience a escribir código y lo discutiremos nuevamente en un mes.