Ajax, que consta de HTML, tecnología JavaScript™, DHTML y DOM, es una manera brillante de transformar engorrosas interfaces web en aplicaciones Ajax interactivas. Este artículo, escrito por un experto en Ajax, demuestra cómo estas tecnologías funcionan juntas (desde una descripción general hasta una discusión detallada) para hacer realidad el desarrollo web eficiente. También desmitifica los conceptos básicos de Ajax, incluido el objeto XMLHttpRequest.
Hace cinco años, si no conocías XML, eras un patito feo al que nadie tomaba en serio. Hace dieciocho meses, Ruby se convirtió en el centro de atención y los programadores que no conocían a Ruby solo podían sentarse en el banquillo. Hoy en día, si quieres estar al día con las últimas novedades tecnológicas, tu destino es Ajax.
Pero Ajax es más que una moda pasajera: es una forma poderosa de crear sitios web que no es tan difícil como aprender un idioma completamente nuevo.
Pero antes de entrar en detalles sobre qué es Ajax, tomemos unos minutos para comprender qué hace Ajax. Actualmente, existen dos opciones básicas a la hora de escribir aplicaciones:
· Aplicaciones de escritorio · Aplicaciones web
Las dos son similares, las aplicaciones de escritorio suelen venir en CD (a veces descargables desde un sitio web) y se instalan completamente en el ordenador superior. Las aplicaciones de escritorio pueden usar Internet para descargar actualizaciones, pero el código que ejecuta estas aplicaciones está en la computadora de escritorio. Las aplicaciones web se ejecutan en un servidor web en algún lugar; no es sorprendente que se acceda a dichas aplicaciones a través de un navegador web.
Sin embargo, más importante que dónde se coloca el código que ejecuta estas aplicaciones es cómo funcionan las aplicaciones e interactúan con ellas. Las aplicaciones de escritorio son generalmente rápidas (se ejecutan directamente en su computadora sin esperar una conexión a Internet), tienen una hermosa interfaz de usuario (generalmente depende del sistema operativo) y son notablemente dinámicas. Puede hacer clic, seleccionar, escribir, abrir menús y submenús, navegar y básicamente no esperar nunca.
Las aplicaciones web, por otro lado, son la última tendencia y brindan servicios que no son posibles en el escritorio (como Amazon.com y eBay). Sin embargo, con el poder de la Web surge la necesidad de esperar, esperar a que el servidor responda, esperar a que se actualice la pantalla, esperar a que regrese la solicitud y generar una nueva página.
Obviamente esto es una simplificación excesiva, pero el concepto básico es este. Como habrás adivinado, Ajax intenta unir la funcionalidad y la interactividad de las aplicaciones de escritorio con las aplicaciones web en constante evolución. Puede utilizar interfaces de usuario dinámicas y controles atractivos como los que se encuentran en las aplicaciones de escritorio, pero en una aplicación web.
¿Qué estás esperando? Echemos un vistazo a cómo Ajax puede transformar interfaces web torpes en aplicaciones Ajax responsivas.
Tecnología antigua, trucos nuevos
Cuando se trata de Ajax, en realidad implica una variedad de tecnologías, y su uso flexible requiere una comprensión profunda de estas diferentes tecnologías (los primeros artículos de esta serie analizarán cada una de estas tecnologías por separado). La buena noticia es que probablemente ya esté muy familiarizado con la mayoría de estas tecnologías y, lo que es aún mejor, son fáciles de aprender y no tan difíciles como un lenguaje de programación completo como Java o Ruby.
Las siguientes son las tecnologías básicas utilizadas en las aplicaciones Ajax:
·HTML se utiliza para crear formularios web y determinar los campos utilizados por otras partes de la aplicación.
· El código JavaScript es el código central que ejecuta aplicaciones Ajax y ayuda a mejorar la comunicación con las aplicaciones del servidor.
·DHTML o HTML dinámico para actualizar formularios dinámicamente. Usaremos divs, spans y otros elementos HTML dinámicos para marcar HTML.
·El modelo de objetos de documento DOM se utiliza para procesar (a través de código JavaScript) la estructura de HTML y (en algunos casos) el XML devuelto por el servidor.
Definición de Ajax
Por cierto, Ajax es la abreviatura de JavaScript asíncrono y XML (y DHTML, etc.). Esta frase fue acuñada por Jesse James Garrett de Adaptive Path (ver Recursos) y, como explica Jesse, no es un acrónimo.
Analicemos más a fondo las responsabilidades de estas tecnologías. Hablaré de estas tecnologías en profundidad en artículos futuros, pero por ahora sólo familiarícese con los componentes y las tecnologías. Cuanto más familiarizado esté con estos códigos, más fácil será pasar de una comprensión dispersa de estas tecnologías a una comprensión real de estas tecnologías (lo que también abre verdaderamente la puerta al desarrollo de aplicaciones web).
Objeto XMLHttpRequest
El único objeto que debe comprender también puede ser el más desconocido para usted: XMLHttpRequest. Este es un objeto JavaScript y crearlo es simple, como se muestra en el Listado 1.
Listado 1. Creación de un nuevo objeto XMLHttpRequest
Analizaremos este objeto más a fondo en el próximo artículo, pero por ahora sepa que este es el objeto que maneja todas las comunicaciones del servidor. Antes de continuar leyendo, detente a pensar en esto: la tecnología JavaScript es la que habla con el servidor a través del objeto XMLHttpRequest. Este no es un flujo de aplicaciones ordinario, y de aquí proviene el poder de Ajax.
En una aplicación web típica, el usuario completa los campos del formulario y hace clic en el botón Enviar. Luego, el formulario completo se envía al servidor, que lo reenvía a un script que maneja el formulario (generalmente PHP o Java, tal vez un proceso CGI o algo similar), y luego envía de vuelta una página nueva cuando el script está completo. La página puede ser HTML con un nuevo formulario ya completado con algunos datos, puede ser una página de confirmación o puede ser una página con algunas opciones seleccionadas según los datos ingresados en el formulario original. Por supuesto, el usuario debe esperar mientras el script o programa en el servidor procesa y devuelve el nuevo formulario. La pantalla se queda en blanco y espera hasta que el servidor devuelva los datos antes de volver a dibujarlos. Esta es la razón por la cual la interactividad es pobre, el usuario no recibe retroalimentación inmediata, por lo que se siente diferente a una aplicación de escritorio.
Ajax básicamente coloca la tecnología JavaScript y el objeto XMLHttpRequest entre el formulario web y el servidor. Cuando el usuario completa el formulario, los datos se envían a algún código JavaScript en lugar de directamente al servidor. En cambio, el código JavaScript captura los datos del formulario y envía una solicitud al servidor. Al mismo tiempo, el formulario en la pantalla del usuario no parpadeará, desaparecerá ni se retrasará. En otras palabras, el código JavaScript envía la solicitud entre bastidores sin que el usuario sepa siquiera que se está realizando la solicitud. Aún mejor, la solicitud se envía de forma asíncrona, lo que significa que el código JavaScript (y el usuario) no tienen que esperar una respuesta del servidor. Para que el usuario pueda continuar ingresando datos, desplazarse y usar la aplicación.
Luego, el servidor devuelve los datos al código JavaScript (aún en el formulario web), que decide qué hacer con los datos. Actualiza los datos del formulario rápidamente, dando la impresión de que la solicitud se completa instantáneamente, sin que el formulario se envíe o actualice y el usuario obtenga nuevos datos. El código JavaScript puede incluso realizar algunos cálculos sobre los datos recibidos y enviar otra solicitud, ¡todo sin la intervención del usuario! Este es el poder de XMLHttpRequest. Puede interactuar con el servidor por sí solo según sea necesario, y el usuario puede incluso ignorar por completo lo que sucede detrás de escena. El resultado es una experiencia dinámica, receptiva y altamente interactiva similar a una aplicación de escritorio, pero con todo el poder de Internet detrás.
Después deagregar algo de JavaScript
para manejar XMLHttpRequest, el otro código JavaScript es muy simple. De hecho, usaremos código JavaScript para realizar tareas muy básicas:
· Obtener datos del formulario: el código JavaScript puede extraer fácilmente datos de un formulario HTML y enviarlos al servidor.
·Modificar datos en el formulario: Actualizar el formulario también es fácil, desde configurar valores de campo hasta reemplazar rápidamente imágenes.
·Analizar HTML y XML: utilice código JavaScript para manipular el DOM (consulte la siguiente sección) y procesar la estructura de los datos XML devueltos por el servidor de formularios HTML.
Para los dos primeros puntos, debe estar muy familiarizado con el método getElementById(), como se muestra en el Listado 2.
Listado 2. Capturar y configurar valores de campo con código JavaScript
// Obtenemos el valor del campo "teléfono" y lo metemos en una variable llamada teléfono
var phone = document.getElementById("phone").value
// Establece algunos valores en un formulario usando una matriz llamada respuesta;
document.getElementById("pedido").valor = respuesta[0];
document.getElementById("address").value = respuesta[1];
No hay nada especial que destacar aquí, ¡es genial! Debes darte cuenta de que aquí no hay nada terriblemente complicado. Una vez que domine XMLHttpRequest, el resto de su aplicación Ajax es código JavaScript simple, como se muestra en el Listado 2, mezclado con una pequeña cantidad de HTML. Al mismo tiempo, también necesitamos usar un poco de DOM, así que echemos un vistazo.
Terminando con DOM
Finalmente está DOM, el Modelo de Objetos de Documento. El DOM puede resultar un poco intimidante para algunos lectores. Los diseñadores de HTML rara vez lo utilizan, e incluso los programadores de JavaScript rara vez lo utilizan a menos que quieran completar una tarea de programación de alto nivel. Los programas complejos de Java y C/C++ hacen un uso intensivo del DOM, lo que puede explicar por qué se considera que el DOM es difícil de aprender.
Afortunadamente, trabajar con el DOM en tecnología JavaScript es fácil y muy intuitivo. Ahora bien, convencionalmente probablemente deberías explicar cómo usar el DOM, o al menos dar algún código de ejemplo, pero hacerlo también podría inducirte a error. Incluso si ignoras el DOM, aún puedes profundizar en Ajax, y ese es el enfoque que voy a adoptar. Revisaremos el DOM en un artículo futuro, pero por ahora basta con saber que es posible que lo necesites. Profundizaremos en el DOM cuando necesitemos pasar XML entre el código JavaScript y el servidor y cambiar formularios HTML. Puedes hacer algún trabajo interesante sin él, así que deja el DOM a un lado por ahora.
Obtención del objeto Solicitud
Con los conocimientos básicos anteriores, echemos un vistazo a algunos ejemplos específicos. XMLHttpRequest está en el corazón de las aplicaciones Ajax y puede resultar desconocido para muchos lectores, así que comencemos por ahí. Como puede ver en el Listado 1, crear y usar este objeto es muy simple, ¿no es así? Esperar.
¿Recuerdas aquellas desagradables guerras de navegadores de hace unos años? Nada da los mismos resultados en diferentes navegadores. Lo creas o no, estas guerras todavía continúan, aunque en menor escala. Pero, curiosamente, XMLHttpRequest se convirtió en una de las víctimas de esta guerra. Por lo tanto, obtener el objeto XMLHttpRequest puede requerir un enfoque diferente. Lo explicaré en detalle a continuación.
Uso del navegador de Microsoft
El navegador de Microsoft Internet Explorer utiliza un analizador MSXML para procesar XML (puede obtener más información sobre MSXML en Recursos). Por lo tanto, si escribe una aplicación Ajax que interactúa con Internet Explorer, debe crear objetos de una manera especial.
Pero no es tan simple. En realidad, existen dos versiones diferentes de MSXML dependiendo de la versión de la tecnología JavaScript instalada en Internet Explorer, por lo que debes escribir código separado para cada caso. Consulte el Listado 3, que contiene código que crea una XMLHttpRequest en un navegador de Microsoft.
Listado 3. Crear un objeto XMLHttpRequest en el navegador de Microsoft
var xmlHttp = false;
intentar {
xmlHttp = nuevo ActiveXObject("Msxml2.XMLHTTP");
} atrapar (e) {
intentar {
xmlHttp = nuevo ActiveXObject("Microsoft.XMLHTTP");
} atrapar (e2) {
xmlHttp = falso;
}
}
Puede que aún no entiendas completamente el código, pero está bien. Al final de esta serie de artículos, tendrá una comprensión más profunda de la programación JavaScript, el manejo de errores, la compilación condicional y más. Ahora sólo recuerde las dos líneas de código:
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
y
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");.
Básicamente, estas dos líneas de código intentan crear un objeto usando una versión de MSXML y, si eso falla, crean el objeto usando otra versión. No está mal, ¿verdad? Si ninguno de los dos tiene éxito, la variable xmlHttp se establece en falso, indicando al código que hay un problema. Si esto ocurre, puede deberse a que está instalado un navegador que no es de Microsoft y requiere un código diferente.
Manejo de navegadores Mozilla y que no sean de Microsoft
Si elige un navegador que no sea Internet Explorer, o si escribe código para un navegador que no sea de Microsoft, necesitará usar un código diferente. En realidad, es una línea simple de código que se muestra en el Listado 1:
var xmlHttp = nuevo objeto XMLHttpRequest;.
Esta línea de código mucho más simple crea un objeto XMLHttpRequest en Mozilla, Firefox, Safari, Opera y básicamente cualquier navegador que no sea de Microsoft que admita Ajax en cualquier forma.
La clavepara combinar esto
es admitir todos los navegadores. ¿Quién quiere escribir una aplicación que sólo funcione con Internet Explorer o con navegadores que no sean de Microsoft? ¿O peor aún, escribir una solicitud dos veces? ¡Por supuesto que no! Por lo tanto, el código debe ser compatible tanto con Internet Explorer como con navegadores que no sean de Microsoft. El Listado 4 muestra dicho código.
Listado 4. Crear un objeto XMLHttpRequest de manera que admita múltiples navegadores
/* Crea un nuevo objeto XMLHttpRequest para comunicarse con el servidor web */
var xmlHttp = falso;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
intentar {
xmlHttp = nuevo ActiveXObject("Msxml2.XMLHTTP");
} atrapar (e) {
intentar {
xmlHttp = nuevo ActiveXObject("Microsoft.XMLHTTP");
} atrapar (e2) {
xmlHttp = falso;
}
}
@end @*/
if (!xmlHttp && tipo de XMLHttpRequest != 'indefinido') {
xmlHttp = nueva XMLHttpRequest();
}
Por ahora, ignore los símbolos extraños comentados, como @cc_on, que son comandos especiales del compilador de JavaScript que se analizarán en detalle en el próximo artículo sobre XMLHttpRequest. El núcleo de este código se divide en tres pasos:
1. Cree una variable xmlHttp para hacer referencia al objeto XMLHttpRequest que se creará.
2. Intente crear el objeto en el navegador de Microsoft:
1) Intente crearlo utilizando el objeto Msxml2.XMLHTTP.
2) Si falla, intente nuevamente con el objeto Microsoft.XMLHTTP.
2. Si aún no se crea xmlHttp, cree el objeto de una forma que no sea de Microsoft.
Finalmente, xmlHttp debe hacer referencia a un objeto XMLHttpRequest válido, sin importar qué navegador esté ejecutando.
Una pequeña nota sobre seguridad.
¿Qué tal la seguridad? Los navegadores ahora permiten a los usuarios aumentar su nivel de seguridad, desactivar la tecnología JavaScript y desactivar cualquier opción en el navegador. En este caso, el código no funcionará de todos modos. En este punto, es necesario abordar el problema de manera adecuada, lo que requiere un artículo aparte para más adelante (esta serie es bastante larga, ¿verdad? No te preocupes, es posible que la obtengas antes de terminar de leer). Ahora escribamos un fragmento de código que sea robusto pero no perfecto, que sea bueno para dominar Ajax. Discutiremos esto con más detalle más adelante.
Solicitud/Respuesta en el mundo Ajax
Ahora que hemos introducido Ajax, tenemos un conocimiento básico del objeto XMLHttpRequest y cómo crearlo. Si ha leído con atención, probablemente ya sepa que es la tecnología JavaScript la que se ocupa de las aplicaciones web en el servidor, en lugar de los formularios HTML que se envían directamente a esa aplicación.
¿Qué falta? Exactamente cómo utilizar XMLHttpRequest. Debido a que este código es tan importante que cada aplicación Ajax que escriba lo usará de alguna forma, comencemos viendo cómo se ve el modelo básico de solicitud/respuesta de Ajax.
Realizar la solicitud
Ahora que tiene un nuevo objeto XMLHttpRequest, dejemos que trabaje un poco. Primero, necesita un método JavaScript que la página web pueda llamar (por ejemplo, cuando el usuario ingresa texto o selecciona un elemento de un menú). El siguiente es el proceso que es básicamente el mismo en todas las aplicaciones Ajax:
1. Obtener los datos requeridos del formulario web.
2. Cree la URL para conectarse.
3. Abra una conexión al servidor.
4. Configure la función que ejecutará el servidor una vez finalizada.
5. Envíe una solicitud.
Los métodos Ajax de muestra en el Listado 5 están organizados en este orden:
Listado 5. Realizar una solicitud Ajax
función llamadaServidor() {
//Obtiene la ciudad y el estado desde el formulario web
var ciudad = document.getElementById("ciudad").value;
var estado = document.getElementById("estado").valor;
//Solo continúa si hay valores para ambos campos
if ((ciudad == null) || (ciudad == "")) retorno;
if ((state == null) || (state == "")) return
// Crea la URL para conectarte;
var url = "/scripts/getZipCode.php?city=" + escape(city) + "&state=" + escape(state)
;
xmlHttp.open("GET", url, true);
// Configura una función para que el servidor se ejecute cuando esté listo
xmlHttp.onreadystatechange = updatePage;
// Enviar la solicitud
xmlHttp.send(nulo);
}
El significado de la mayoría de los códigos es muy claro. El código al principio utiliza código JavaScript básico para obtener los valores de varios campos del formulario. Luego configure un script PHP como destino del enlace. Tenga en cuenta la forma en que se especifica la URL del script, la ciudad y el estado (del formulario) se agregan a la URL mediante parámetros GET simples.
Luego se abre una conexión, que es la primera vez que ve que se utiliza XMLHttpRequest. Se especifica el método de conexión (GET) y la URL a la que conectarse. El último parámetro, si se establece en verdadero, solicitará una conexión asincrónica (este es el origen de Ajax). Si se usa falso, el código esperará una respuesta del servidor después de realizar la solicitud. Si se establece en verdadero, los usuarios aún pueden usar el formulario (e incluso llamar a otros métodos de JavaScript) mientras el servidor maneja las solicitudes en segundo plano.
El atributo onreadystatechange de xmlHttp (recuerde, esta es una instancia de objeto XMLHttpRequest) le dice al servidor qué hacer después de que haya terminado de ejecutarse (lo que puede tardar cinco minutos o cinco horas). Debido a que el código no está esperando al servidor, debe informarle qué hacer para que usted pueda responder. En este ejemplo, si el servidor ha terminado de procesar la solicitud, se activará un método especial llamado updatePage().
Finalmente, se llama a send() con el valor nulo. Debido a que los datos que se enviarán al servidor (ciudad y estado) se agregaron a la URL de la solicitud, no es necesario enviar datos en la solicitud. De esta manera se realiza la solicitud y el servidor funciona según su solicitud.
Si no encuentra nada nuevo, ¡debería apreciar lo simple y directo que es! Aparte de tener en cuenta la naturaleza asincrónica de Ajax, todo esto es bastante simple. Agradezca que Ajax le permita concentrarse en escribir hermosas aplicaciones e interfaces en lugar de preocuparse por el complejo código de solicitud/respuesta HTTP.
El código del Listado 5 ilustra la facilidad de uso de Ajax. Los datos son texto simple y se pueden utilizar como parte de la URL de solicitud. Envíe solicitudes con GET en lugar del POST más complejo. No hay XML ni encabezados de contenido para agregar, ni datos para enviar en el cuerpo de la solicitud; en otras palabras, esto es la utopía de Ajax;
No se preocupe, las cosas se complicarán más a medida que se desarrolle esta serie de artículos. Verá cómo enviar una solicitud POST, cómo configurar los encabezados de la solicitud y el tipo de contenido, cómo codificar XML en el mensaje, cómo aumentar la seguridad de la solicitud y ¡hay mucho más que puede hacer! No se preocupe por esas dificultades por ahora, simplemente domine los aspectos básicos y pronto crearemos un conjunto completo de bibliotecas de herramientas Ajax.
Manejando la respuesta
Ahora viene la respuesta del servidor. Sólo dos cosas que debes saber por ahora:
· No hacer nada hasta que el valor de la propiedad xmlHttp.readyState sea igual a 4.
·El servidor completará la propiedad xmlHttp.responseText con la respuesta.
El primero de ellos, el estado listo, se analizará en detalle en el próximo artículo y aprenderá más sobre las etapas de una solicitud HTTP de lo que probablemente pensaba. Por ahora basta con comprobar un valor específico (4) (habrá más valores que cubrir en el próximo artículo). Segundo punto, use la propiedad xmlHttp.responseText para obtener la respuesta del servidor, es muy simple. El servidor puede llamar al método de ejemplo del Listado 6 en función de los datos enviados en el Listado 5.
Listado 6. Manejo de
la función de respuesta del servidor updatePage() {
si (xmlHttp.readyState == 4) {
var respuesta = xmlHttp.responseText;
document.getElementById("zipCode").value = respuesta;
}
}
Los códigos tampoco son difíciles ni complejos. Espera a que el servidor llame y, si está listo, establece el valor de otro campo del formulario utilizando el valor devuelto por el servidor (aquí el código postal de la ciudad y el estado ingresado por el usuario). ¡De repente aparece el campo zipCode que contiene el código postal sin que el usuario presione ningún botón! Esto es lo que mencioné anteriormente como aplicación de escritorio. Respuesta rápida, sensación dinámica, etc., todo gracias a un pequeño fragmento de código Ajax.
Los lectores atentos pueden notar que zipCode es un campo de texto normal. Una vez que el servidor devuelve la codificación ZIP, el método updatePage() establece el valor de ese campo con la codificación ZIP de ciudad/estado, que el usuario puede anular. Esto se hace por dos razones: para mantener el ejemplo simple y para ilustrar que a veces es posible que desee que el usuario pueda modificar los datos devueltos por el servidor. Tenga en cuenta estas dos cosas, son importantes para un buen diseño de interfaz de usuario.
¿Qué más hay
para conectarse a un formulario web
?En realidad no queda mucho. Un método de JavaScript captura la información que el usuario ingresa en el formulario y la envía al servidor, y el otro método de JavaScript escucha y procesa la respuesta y establece el valor del campo cuando regresa la respuesta. En realidad, todo esto se basa en llamar al primer método de JavaScript, que inicia todo el proceso. La solución más obvia es agregar un botón al formulario HTML, pero eso es 2001, ¿no crees? Usemos tecnología JavaScript como el Listado 7.
Listado 7. Iniciando un proceso Ajax
Ciudad: onChange="llamarServidor();" /> Estado: Código postal:
Si esto le parece un fragmento de código bastante común, tiene razón: ¡lo es! Cuando el usuario ingresa un nuevo valor en el campo ciudad o estado, se activa el método callServer() y Ajax comienza a ejecutarse. ¿Entiendes un poco lo que está pasando? Bueno, ¡eso es todo!
Conclusión
Ahora probablemente esté listo para comenzar a escribir su primera aplicación Ajax y al menos quiera leer los artículos de los recursos con atención, ¿verdad? Pero puede comenzar con una idea básica de cómo funcionan estas aplicaciones y una comprensión básica del objeto XMLHttpRequest. En la próxima entrega, dominará este objeto y aprenderá cómo manejar la comunicación entre JavaScript y el servidor, cómo usar formularios HTML y cómo obtener un identificador DOM.
Ahora tómate un momento para considerar cuán poderosas pueden ser las aplicaciones Ajax. Imagine un formulario web que respondiera instantáneamente cuando hiciera clic en un botón, ingresara un campo, seleccionara una opción de un cuadro combinado o arrastrara el mouse por la pantalla. Piense en lo que realmente significa async, piense en el código JavaScript ejecutándose y no esperando a que el servidor responda a su solicitud. ¿Qué tipo de problemas encontrarás? ¿En qué tipo de campo entrará? Dado este nuevo enfoque, ¿cómo deberíamos cambiar el diseño del formulario al programar?
Si dedica un poco de tiempo a estos temas, obtendrá más que simplemente cortar/pegar código en una aplicación que no comprende en absoluto. En la próxima entrega, pondremos estos conceptos en práctica y detallaremos el código necesario para que la aplicación funcione de esta manera. Por ahora, disfrute de las posibilidades que Ajax tiene para ofrecer.