JavaScript en AIRFlash Player 9 y posterior, Adobe AIR 1.0 y posterior AIR modifica de varias maneras el comportamiento típico de objetos comunes de JavaScript. Muchas de estas modificaciones tienen la finalidad de facilitar la escritura de aplicaciones seguras en AIR. Al mismo tiempo, debido a estas diferencias de comportamiento es posible que algunos patrones de codificación de JavaScript, así como las aplicaciones web existentes que utilicen esos patrones, no siempre se ejecutan de la forma prevista en AIR. Para obtener información sobre la corrección de este tipo de problema, consulte Cómo evitar errores de JavaScript relacionados con la seguridad. Entornos limitados en HTMLAIR pone contenido en entornos limitados aislados en función del origen del contenido. Las reglas de entornos limitados son coherentes con la política de "mismo origen" que implementa la mayoría de los navegadores web, además de las reglas para entornos limitados implementados por Adobe Flash Player. Por otra parte, AIR proporciona un nuevo tipo de entorno limitado de la aplicación que contiene y protege el contenido de la aplicación. Para obtener más información sobre los tipos de entornos limitados que puede encontrar al desarrollar aplicaciones de AIR, consulte Entornos limitados de seguridad. El acceso al entorno del motor de ejecución y las API de AIR sólo está disponible para HTML y JavaScript cuando se ejecutan en el entorno limitado de la aplicación Al mismo tiempo, la ejecución y evaluación dinámica de JavaScript, en sus diversas modalidades, está en gran medida restringida en el entorno limitado de la aplicación por razones de seguridad. Estas restricciones rigen independientemente de si la aplicación carga información directamente desde un servidor o no. (Incluso el contenido de los archivos, las cadenas pegadas y la información introducida por el usuario pueden no ser fidedignos). El origen del contenido de una página determina el entorno limitado al que se consigna. En el entorno limitado de la aplicación sólo se pone el contenido cargado desde el directorio de la aplicación (el directorio de instalación al que remite el esquema app: de URL). El contenido cargado desde el sistema de archivos se pone en el entorno limitado local con sistema de archivos o local de confianza, que permite el acceso y la interacción con el contenido del sistema de archivos local, pero no con el contenido remoto. El contenido cargado desde la red se pone en un entorno limitado remoto que corresponde con su dominio de origen. Para que una página de una aplicación pueda interactuar libremente con el contenido de un entorno limitado remoto, la página se puede asignar al mismo dominio que el contenido remoto. Por ejemplo, si es escribe una aplicación que muestra datos de mapas de un servicio de Internet, la página de la aplicación que descarga el contenido del servicio y lo presenta puede asignarse al dominio del servicio. Los atributos para asignar páginas en un entorno limitado remoto y un dominio son atributos nuevos que se añaden a los elementos de frame e iframe en HTML. Para que el contenido de un entorno limitado ajeno a la aplicación pueda utilizar las funciones de AIR de forma segura, se puede establecer un puente de entorno limitado principal. Para que el contenido de la aplicación pueda llamar a métodos y tener acceso a propiedades del contenido de otros entornos limitados, se puede establecer un puente de entorno limitado secundario. La seguridad en este contexto significa que el contenido remoto no puede obtener accidentalmente referencias a objetos, propiedades o métodos que no están expuestos de forma explícita. Sólo pueden pasar por el puente los tipos de datos, funciones y objetos anónimos sencillos. No obstante, aun así debe evitarse exponer explícitamente las funciones que sean potencialmente peligrosas. Por ejemplo: si expusiera una interfaz que permite que un contenido remoto lea y escriba archivos en cualquier parte del sistema del usuario, podría estar facilitando al contenido remoto los medios para causar graves daños al usuario. Función eval() de JavaScriptUna vez que ha terminado de cargarse una página, el uso de la función eval() queda restringido al entorno limitado de la aplicación. Se admiten algunos usos para que datos en formato JSON puedan analizarse con seguridad, pero toda evaluación que arroje sentencias ejecutables producirá un error. En Restricciones de código del contenido en entornos limitados diferentes se describen los usos admitidos de la función eval(). Constructores FunctionEn el entorno limitado de la aplicación pueden utilizarse constructores de función antes de que se termine de cargar una página. Una vez que han terminado todos los controladores de eventos load de la página, no se pueden crear funciones nuevas. Carga de scripts externosLas páginas en HTML del entorno limitado de la aplicación no pueden utilizar la etiqueta script para cargar archivos JavaScript desde fuera del directorio de la aplicación. Para que una página de la aplicación cargue un script desde fuera del directorio de la aplicación, la página debe asignarse a un entorno limitado externo. Objeto XMLHttpRequestAIR proporciona un objeto XMLHttpRequest (XHR) que pueden utilizar las aplicaciones para realizar peticiones de datos. El ejemplo siguiente ilustra una petición de datos sencilla: xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "http:/www.example.com/file.data", true);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
//do something with data...
}
}
xmlhttp.send(null);
A diferencia de los navegadores, AIR permite que el contenido que se ejecuta en el entorno limitado de la aplicación solicite datos de cualquier dominio. El resultado de una petición XHR que contiene una cadena JSON puede producir objetos de datos, a menos que el resultado también contenga código ejecutable. Si hay sentencias ejecutables en el resultado de la XHR, se emite un error y el intento de evaluación falla. Para evitar la inyección accidental de código desde fuentes remotas, las XHR sincrónicas devuelven un resultado vacío si se realizan antes de haberse terminado de cargar la página. Las XHR asíncronas siempre devuelven un resultado después de haberse cargado una página. De forma predeterminada, AIR bloquea las peticiones XMLHttpRequest entre dominios en los entornos limitados ajenos a la aplicación. Una ventana principal en el entorno limitado de la aplicación puede optar por permitir las peticiones entre dominios en un fotograma secundario que contenga contenido en un entorno limitado ajeno a la aplicación definiendo allowCrossDomainXHR -un atributo que añade AIR- en true en el elemento frame o iframe contenedor: <iframe id="mashup"
src="http://www.example.com/map.html"
allowCrossDomainXHR="true"
</iframe>
Nota: si conviene, la clase URLStream de AIR también puede utilizarse para descargar datos.
Si se distribuye una petición XMLHttpRequest a un servidor remoto desde un fotograma o iframe que contenga contenido de la aplicación que se ha asignado a un entorno limitado remoto, asegúrese de que la URL de asignación no oculte la dirección del servidor que se utiliza en la XHR. Tomemos por ejemplo la siguiente definición de iframe, que asigna contenido de la aplicación a un entorno limitado remoto para el dominio example.com: <iframe id="mashup"
src="http://www.example.com/map.html"
documentRoot="app:/sandbox/"
sandboxRoot="http://www.example.com/"
allowCrossDomainXHR="true"
</iframe>
Debido a que el atributo sandboxRoot reasigna la URL raíz de la dirección www.example.com, todas las peticiones se cargan desde el directorio de la aplicación y no desde el servidor remoto. Las peticiones se reasignan independientemente de si derivan de haber visitado distintas páginas o de una petición XMLHttpRequest. Para evitar bloquear accidentalmente las peticiones de datos al servidor remoto, asigne sandboxRoot a un subdirectorio de la URL remota y no a la raíz. No es necesario que exista el directorio. Por ejemplo, para permitir que las peticiones a www.example.com se carguen desde el servidor remoto en lugar del directorio de la aplicación, cambie el iframe anterior a: <iframe id="mashup"
src="http://www.example.com/map.html"
documentRoot="app:/sandbox/"
sandboxRoot="http://www.example.com/air/"
allowCrossDomainXHR="true"
</iframe>
En este caso, sólo se carga localmente el contenido del subdirectorio air. Para obtener más información, consulte Elementos frame e iframe de HTML y Seguridad HTML en Adobe AIR. CookiesEn las aplicaciones de AIR sólo el contenido de los entornos limitados remotos (contenido cargado desde fuentes http: y https:) puede utilizar cookies (la propiedad document.cookie). En el entorno limitado de la aplicación, existen otros medios para almacenar datos persistentes, incluyendo las clases EncryptedLocalStore, SharedObject y FileStream. Objeto ClipboardLa API Clipboard del WebKit funciona con los eventos copy, cut y paste. El objeto de evento que se pasa en estos eventos proporciona acceso al portapapeles a través de la propiedad clipboardData. Para leer o escribir datos en el portapapeles, utilice los siguientes métodos del objeto clipboardData:
El código JavaScript que esté fuera del entorno limitado de la aplicación sólo tiene acceso al portapapeles a través de estos eventos. No obstante, el contenido del entorno limitado de la aplicación tiene acceso directo al portapapeles del sistema a través de la clase Clipboard de AIR. Por ejemplo, se puede utilizar la siguiente sentencia para obtener datos en formato de texto del portapapeles: var clipping = air.Clipboard.generalClipboard.getData("text/plain",
air.ClipboardTransferMode.ORIGINAL_ONLY);
Los tipos de datos MIME válidos son:
Importante: únicamente el contenido del entorno limitado de la aplicación tiene acceso a los datos de archivo que hay en el portapapeles. Si un contenido ajeno a la aplicación intenta acceder a un objeto de archivo desde el portapapeles, se emite un error de seguridad.
Para obtener más información sobre el uso del portapapeles, consulte Copiar y pegar y Using the Pasteboard from JavaScript (Uso del Pasteboard de JavaScript) (Centro de desarrollo de Apple). Arrastrar y colocarLos gestos de arrastrar y colocar hacia dentro y hacia fuera de HTML producen los siguientes eventos del DOM: dragstart, drag, dragend, dragenter, dragover, dragleave y drop. El objeto de evento que se pasa en estos eventos proporciona acceso a los datos arrastrados a través de la propiedad dataTransfer. La propiedad dataTransfer hace referencia a un objeto que proporciona los mismos métodos que el objeto clipboardData asociado con un evento clipboard. Por ejemplo, se puede utilizar la siguiente función para obtener datos en formato de texto de un evento drop: function onDrop(dragEvent){
return dragEvent.dataTransfer.getData("text/plain",
air.ClipboardTransferMode.ORIGINAL_ONLY);
}
El objeto dataTransfer tiene los siguientes miembros importantes:
Para obtener más información sobre cómo ampliar la compatibilidad con arrastrar y colocar en una aplicación de AIR, consulte Operación de arrastrar y colocar en AIR y Using the Drag-and-Drop from JavaScript (Uso de arrastrar y colocar de JavaScript) (Centro de desarrollo de Apple). Propiedades innerHTML y outerHTMLAIR impone restricciones de seguridad en el uso de las propiedades innerHTML y outerHTML para contenido que se ejecuta en el entorno limitado de la aplicación. Previo al evento de cargar la página, así como durante la ejecución de un controlador de eventos de carga, el uso de las propiedades innerHTML y outerHTML es irrestricto. Sin embargo, una vez cargada la página sólo se puede utilizar una propiedad innerHTML o outerHTML para añadir contenido estático al documento. Se pasa por alto toda sentencia en la cadena asignada a innerHTML o outerHTML que produzca código ejecutable. Por ejemplo, si se incluye un atributo callback de evento en la definición de un elemento, no se añade el detector de eventos. Asimismo, no se evalúan las etiquetas <script>. Para obtener más información, consulte Seguridad HTML en Adobe AIR. Métodos Document.write() y Document.writeln()El uso de los métodos write() y writeln() no está restringido en el entorno limitado de la aplicación previo al evento load de la página. Sin embargo, una vez cargada la página, al llamar a cualquiera de estos dos métodos la página no se borra ni se crea una nueva. En un entorno limitado ajeno a la aplicación, al igual que con la mayoría de los navegadores web, cuando se llama a document.write() o writeln() tras haberse terminado de cargar una página, la página actual se borra y se abre una nueva página en blanco. Propiedad Document.designModeDefina la propiedad document.designMode en on para que todos los elementos del documento sean editables. Entre las funciones integradas del editor se encuentran las de editar texto, copiar, pegar, y arrastrar y pegar. Definir designMode en on equivale a definir la propiedad contentEditable del elemento body en true. La propiedad contentEditable puede utilizarse en la mayoría de los elementos HTML para definir qué secciones de un documento son editables. Para obtener más información, consulte Atributo HTML contentEditable. Eventos unload (para objetos body y frameset)En la etiqueta de nivel superior frameset o body de una ventana (incluida la ventana principal de la aplicación) no se debe utilizar un evento unload para responder a la acción de cerrar la ventana (o aplicación). En su lugar, utilice el evento exiting del objeto NativeApplication (para detectar cuándo se cierra una aplicación). O bien, utilice el evento closing del objeto NativeWindow (para detectar cuándo se cierra una ventana). Por ejemplo, el siguiente código JavaScript presenta un mensaje ("Goodbye.") cuando el usuario cierra la aplicación: var app = air.NativeApplication.nativeApplication;
app.addEventListener(air.Event.EXITING, closeHandler);
function closeHandler(event)
{
alert("Goodbye.");
}
No obstante, los scripts sí pueden responder satisfactoriamente al evento unload provocado por la navegación por el contenido de un fotograma, iframe o ventana de nivel superior. Nota: es posible que estas limitaciones se eliminen en una versión futura de Adobe AIR.
Objeto Window en JavaScriptEl objeto Window (ventana) sigue siendo el objeto global en el contexto de la ejecución de JavaScript. En el entorno limitado de la aplicación, AIR añade nuevas propiedades al objeto Window de JavaScript para facilitar el acceso a las clases integradas de AIR, además de importantes objetos host. Por otra parte, algunos métodos y propiedades se comportan de distinta manera, según se encuentren o no en el entorno limitado de la aplicación.
Objeto air.NativeApplicationEl objeto NativeApplication facilita información sobre el estado de la aplicación, distribuye varios eventos importantes a nivel de aplicación y ofrece funciones de utilidad para controlar el comportamiento de la aplicación. Se crea automáticamente una única instancia del objeto NativeApplication, a la que se tiene acceso a través de la propiedad NativeApplication.nativeApplication definida por la clase. Para acceder al objeto desde el código JavaScript se puede usar: var app = window.runtime.flash.desktop.NativeApplication.nativeApplication; O bien, si se ha importado el script AIRAliases.js, se puede utilizar la forma abreviada: var app = air.NativeApplication.nativeApplication; Sólo se tiene acceso al objeto NativeApplication desde el entorno limitado de la aplicación. Para obtener más información sobre el objeto NativeApplication, consulte Trabajo con información sobre el motor de ejecución de AIR y el sistema operativo. Esquema URL de JavaScriptLa ejecución del código definido en un esquema URL de JavaScript (por ejemplo, en href="javascript:alert('Test')") está bloqueada en el entorno limitado de la aplicación. No se emite ningún error. |
|