Trabajo con datos externos



ActionScript 3.0 incluye mecanismos para cargar datos desde fuentes externas. Estas fuentes pueden ser de contenido estático, como archivos de texto, o de contenido dinámico, como un script Web que recupera datos de una base de datos. Se puede aplicar formato a los datos de varias maneras y ActionScript proporciona funcionalidad para descodificar y acceder a los datos. También se pueden enviar datos al servidor externo como parte del proceso de recuperación de datos.

Utilización de las clases URLLoader y URLVariables

ActionScript 3.0 utiliza las clases URLLoader y URLVariables para cargar datos externos. La clase URLLoader descarga datos desde una URL como texto, datos binarios o variables con codificación URL. La clase URLLoader es útil para descargar archivos de texto, XML u otra información para utilizarla en aplicaciones ActionScript dinámicas basadas en datos. La clase URLLoader aprovecha el modelo avanzado de gestión de eventos de ActionScript 3.0, que permite detectar eventos como complete, httpStatus, ioError, open, progress y securityError. El nuevo modelo de gestión de eventos supone una mejora significativa con respecto al uso de los controladores de eventos LoadVars.onData, LoadVars.onHTTPStatus y LoadVars.onLoad en ActionScript 2.0, ya que permite gestionar errores y eventos con mayor eficacia. Para obtener más información sobre la gestión de eventos, consulte Gestión de eventos.

De forma muy similar a las clases XML y LoadVars de versiones anteriores de ActionScript, los datos del URL URLLoader no están disponibles hasta que finaliza la descarga. Para supervisar el progreso de la descarga (bytes cargados y bytes totales) es necesario detectar el evento flash.events.ProgressEvent.PROGRESS que se va a distribuir, aunque si un archivo se carga demasiado rápido, puede ser que no se distribuya un evento ProgressEvent.PROGRESS. Cuando finaliza la descarga de un archivo, se distribuye el evento flash.events.Event.COMPLETE. Los datos cargados se descodifican de la codificación UTF-8 o UTF-16 y se convierten en una cadena.

Nota: si no se establece ningún valor para URLRequest.contentType, los valores se envían como application/x-www-form-urlencoded.

El método URLLoader.load() (y opcionalmente el constructor de la clase URLLoader) admite un solo parámetro, request, que es una instancia de URLRequest. Una instancia de URLRequest contiene toda la información de una sola petición HTTP, como la URL de destino, el método de petición (GET o POST), información de encabezado adicional y el tipo MIME (por ejemplo, cuando se carga contenido XML).

Por ejemplo, para cargar un paquete XML en un script de servidor, se podría usar el siguiente código ActionScript 3.0:

var secondsUTC:Number = new Date().time; 
var dataXML:XML =  
    <login> 
        <time>{secondsUTC}</time> 
        <username>Ernie</username> 
        <password>guru</password> 
    </login>; 
var request:URLRequest = new URLRequest("http://www.yourdomain.com/login.cfm"); 
request.contentType = "text/xml"; 
request.data = dataXML.toXMLString(); 
request.method = URLRequestMethod.POST; 
var loader:URLLoader = new URLLoader(); 
try 
{ 
    loader.load(request); 
} 
catch (error:ArgumentError) 
{ 
    trace("An ArgumentError has occurred."); 
} 
catch (error:SecurityError) 
{ 
    trace("A SecurityError has occurred."); 
}

El fragmento de código anterior crea una instancia de XML denominada dataXML que contiene un paquete XML que se enviará al servidor. A continuación, se establece la propiedad contentType de URLRequest en "text/xml" y la propiedad data de URLRequest en el contenido del paquete XML, que se convierte en una cadena mediante el método XML.toXMLString(). Finalmente, se crea una nueva instancia de URLLoader y se envía la petición al script remoto mediante el método URLLoader.load().

Hay tres formas posibles de especificar parámetros para pasarlos en una petición de URL:

  • En el constructor de URLVariables

  • En el método URLVariables.decode()

  • Como propiedades específicas en el propio objeto URLVariables

Cuando se definen variables en el constructor de URLVariables o en el método URLVariables.decode(), hay que asegurarse de que se codifica como URL el carácter ampersand porque tiene un significado especial y actúa como delimitador. Por ejemplo, si se pasa un ampersand, es necesario codificarlo como URL cambiando & por %26, ya que el ampersand actúa como delimitador de los parámetros.

Carga de datos desde documentos externos

Cuando se generan aplicaciones dinámicas con ActionScript 3.0, es recomendable cargar datos de archivos externos o scripts de servidor. De esta forma es posible generar aplicaciones dinámicas sin tener que editar o recompilar los archivos de ActionScript. Por ejemplo, si se genera una aplicación de "sugerencia del día", se puede escribir un script de servidor que recupere una sugerencia aleatoria de una base de datos y la guarde en un archivo de texto una vez al día. Luego la aplicación ActionScript puede cargar el contenido de un archivo de texto estático en lugar de consultar la base de datos cada vez.

El siguiente fragmento de código crea un objeto URLRequest y URLLoader, que carga el contenido de un archivo de texto externo, params.txt:

var request:URLRequest = new URLRequest("params.txt"); 
var loader:URLLoader = new URLLoader(); 
loader.load(request);

Se puede simplificar el fragmento de código anterior del siguiente modo:

var loader:URLLoader = new URLLoader(new URLRequest("params.txt"));

De forma predeterminada, si no se define un método de petición, Flash Player y Adobe AIR cargan el contenido con el método HTTP GET. Si se desea enviar los datos con el método POST, es necesario establecer la propiedad request.method en POST con la constante estática URLRequestMethod.POST, como se muestra en el siguiente código:

var request:URLRequest = new URLRequest("sendfeedback.cfm"); 
request.method = URLRequestMethod.POST;

El documento externo, params.txt, que se carga en tiempo de ejecución contiene los siguientes datos:

monthNames=January,February,March,April,May,June,July,August,September,October,November,December&dayNames=Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday

El archivo contiene dos parámetros: monthNames y dayNames. Cada parámetro contiene una lista separada por comas que se analiza como cadenas. Esta lista se puede dividir en un conjunto, mediante el método String.split().

Conviene evitar la utilización de palabras reservadas y construcciones del lenguaje como nombres de variables en archivos de datos externos, ya que dificulta la lectura y depuración del código.

Cuando se han cargado los datos, se distribuye el evento Event.COMPLETE y el contenido del documento externo está disponible para utilizarlo en la propiedad data de URLLoader, como se muestra en el siguiente código:

private function completeHandler(event:Event):void 
{ 
    var loader2:URLLoader = URLLoader(event.target); 
    trace(loader2.data); 
}

Si el documento remoto contiene pares nombre-valor, se pueden analizar los datos con la clase URLVariables, si se pasa el contenido del archivo cargado, como se muestra a continuación:

private function completeHandler(event:Event):void 
{ 
    var loader2:URLLoader = URLLoader(event.target); 
    var variables:URLVariables = new URLVariables(loader2.data); 
    trace(variables.dayNames); 
}

Cada par nombre-valor del archivo externo se crea como una propiedad del objeto URLVariables. Cada propiedad del objeto de variables del ejemplo de código anterior se trata como una cadena. Si el valor del par nombre-valor es una lista de elementos, se puede convertir la cadena en un conjunto, mediante una llamada al método String.split(), como se muestra a continuación:

var dayNameArray:Array = variables.dayNames.split(",");
Si se cargan datos numéricos de archivos de texto externos, es necesario convertir los valores en valores numéricos, mediante una función de nivel superior como int(), uint() o Number().

En lugar de cargar el contenido del archivo remoto como una cadena y crear un nuevo objeto URLVariables, se puede establecer la propiedad URLLoader.dataFormat en una de las propiedades estáticas de la clase URLLoaderDataFormat. Los tres valores posibles para la propiedad URLLoader.dataFormat son los siguientes:

  • URLLoaderDataFormat.BINARY: la propiedad URLLoader.data contendrá datos binarios almacenados en un objeto ByteArray.

  • URLLoaderDataFormat.TEXT: la propiedad URLLoader.data contendrá texto en un objeto String.

  • URLLoaderDataFormat.VARIABLES: la propiedad URLLoader.data contendrá variables con codificación URL almacenadas en un objeto URLVariables.

En el código siguiente se muestra que, al establecer la propiedad URLLoader.dataFormat en URLLoaderDataFormat.VARIABLES, se permite analizar automáticamente los datos cargados en un objeto URLVariables:

package 
{ 
    import flash.display.Sprite; 
    import flash.events.*; 
    import flash.net.URLLoader; 
    import flash.net.URLLoaderDataFormat; 
    import flash.net.URLRequest; 
 
    public class URLLoaderDataFormatExample extends Sprite 
    { 
        public function URLLoaderDataFormatExample() 
        { 
            var request:URLRequest = new URLRequest("http://www.[yourdomain].com/params.txt"); 
            var variables:URLLoader = new URLLoader(); 
            variables.dataFormat = URLLoaderDataFormat.VARIABLES; 
            variables.addEventListener(Event.COMPLETE, completeHandler); 
            try 
            { 
                variables.load(request); 
            }  
            catch (error:Error) 
            { 
                trace("Unable to load URL: " + error); 
            } 
        } 
        private function completeHandler(event:Event):void 
        { 
        var loader:URLLoader = URLLoader(event.target); 
        trace(loader.data.dayNames); 
        } 
    } 
}
Nota: el valor predeterminado de URLLoader.dataFormat es URLLoaderDataFormat.TEXT.

Como se muestra en el siguiente ejemplo, cargar XML de un archivo externo equivale a cargar URLVariables. Se puede crear una instancia de URLRequest y una instancia de URLLoader, y utilizarlas para descargar un documento XML remoto. Cuando el archivo se ha descargado completamente, se distribuye el evento Event.COMPLETE y el contenido del archivo externo se convierte en una instancia de XML, que puede analizarse con los métodos y propiedades de XML.

package 
{ 
    import flash.display.Sprite; 
    import flash.errors.*; 
    import flash.events.*; 
    import flash.net.URLLoader; 
    import flash.net.URLRequest; 
 
    public class ExternalDocs extends Sprite 
    { 
        public function ExternalDocs() 
        { 
            var request:URLRequest = new URLRequest("http://www.[yourdomain].com/data.xml"); 
            var loader:URLLoader = new URLLoader(); 
            loader.addEventListener(Event.COMPLETE, completeHandler); 
            try 
            { 
                loader.load(request); 
            } 
            catch (error:ArgumentError) 
            { 
                trace("An ArgumentError has occurred."); 
            } 
            catch (error:SecurityError) 
            { 
                trace("A SecurityError has occurred."); 
            } 
        } 
        private function completeHandler(event:Event):void 
        { 
            var dataXML:XML = XML(event.target.data); 
            trace(dataXML.toXMLString()); 
        } 
    } 
}

Comunicación con scripts externos

Además de cargar archivos de datos externos, se puede utilizar la clase URLVariables para enviar variables a un script de servidor y procesar la respuesta del servidor. Esto resulta útil, por ejemplo, si se programa un juego y se desea enviar la puntuación del usuario a un servidor para calcular si debe añadirse o no a la lista de mejores puntuaciones, o incluso enviar la información de inicio de sesión de un usuario a un servidor para que lo valide. Un script de servidor puede procesar el nombre de usuario y la contraseña, validarla en una base de datos y devolver la confirmación de si las credenciales suministradas del usuario son válidas.

El siguiente fragmento de código crea un objeto URLVariables denominado variables, que crea una nueva variable denominada name. A continuación, se crea un objeto URLRequest que especifica el URL del script de servidor donde se enviarán las variables. Luego se establece la propiedad method del objeto URLRequest para enviar las variables como una petición HTTP POST. Para añadir el objeto URLVariables a la petición de URL, se establece la propiedad data del objeto URLRequest en el objeto URLVariables creado previamente. Finalmente, se crea la instancia de URLLoader y se llama al método URLLoader.load(), que inicia la petición.

var variables:URLVariables = new URLVariables("name=Franklin"); 
var request:URLRequest = new URLRequest(); 
request.url = "http://www.[yourdomain].com/greeting.cfm"; 
request.method = URLRequestMethod.POST; 
request.data = variables; 
var loader:URLLoader = new URLLoader(); 
loader.dataFormat = URLLoaderDataFormat.VARIABLES; 
loader.addEventListener(Event.COMPLETE, completeHandler); 
try 
{ 
    loader.load(request); 
} 
catch (error:Error) 
{ 
    trace("Unable to load URL"); 
} 
 
function completeHandler(event:Event):void 
{ 
    trace(event.target.data.welcomeMessage); 
}

El código siguiente incluye el contenido del documento greeting.cfm de Adobe ColdFusion® utilizado en el ejemplo anterior:

<cfif NOT IsDefined("Form.name") OR Len(Trim(Form.Name)) EQ 0> 
    <cfset Form.Name = "Stranger" /> 
</cfif> 
<cfoutput>welcomeMessage=#UrlEncodedFormat("Welcome, " & Form.name)# 
</cfoutput>