Utilización de la carga y descarga de archivos

La clase FileReference permite añadir la capacidad de carga y descarga de archivos entre un cliente y un servidor. Mediante un cuadro de diálogo (como el cuadro de diálogo Abrir del sistema operativo Windows), se solicita a los usuarios que seleccionen un archivo para cargar o una ubicación para la descarga.

Todos los objetos FileReference que se crean con ActionScript hacen referencia a un único archivo en el disco duro del usuario. Estos objetos tienen propiedades que contienen información sobre el tamaño, tipo, nombre, fecha de creación y fecha de modificación del archivo.

NOTA

 

La propiedad creator sólo se utiliza en Mac OS. En todas las demás plataformas se devuelve null.

Se puede crear una instancia de la clase FileReference de dos formas distintas. Utilizando el operador new, como se muestra en el siguiente ejemplo:

import flash.net.FileReference;
var myFileReference:FileReference = new FileReference();

O bien, llamando al método FileReferenceList.browse(), que abre un cuadro de diálogo en el sistema del usuario en el que se le solicita que seleccione uno o varios archivos para cargar y, a continuación, crea una matriz de objetos FileReference si el usuario selecciona uno o varios archivos correctamente. Cada objeto FileReference representa un archivo seleccionado por el usuario en el cuadro de diálogo. Un objeto FileReference no contiene ningún dato en las propiedades de FileReference (como name, size o modificationDate) hasta que se produce una de las situaciones siguientes:

NOTA

 

Cuando se realiza una descarga, sólo la propiedad FileReference.name se llena antes de finalizar la descarga. Una vez finalizada la descarga, todas las propiedades están disponibles.

Mientras se ejecutan las llamadas a los métodos FileReference.browse(), FileReferenceList.browse() o FileReference.download(), la mayoría de los reproductores continúan la reproducción del archivo SWF.

Subtemas

Clase FileReference
Carga de archivos en un servidor
Descarga de archivos de un servidor
Clase FileReferenceList

Clase FileReference

La clase FileReference permite cargar y descargar archivos entre el equipo de un usuario y un servidor. El sistema operativo pide al usuario mediante un cuadro de diálogo que seleccione un archivo para cargar o una ubicación para descargar. Cada objeto FileReference hace referencia a un archivo único en el disco del usuario y tiene propiedades que contienen información sobre tamaño, tipo, nombre, fecha de creación, fecha de modificación y creador del archivo.

Las instancias de FileReference se pueden crear de dos formas:

Para las operaciones de carga y descarga, un archivo SWF sólo puede acceder a archivos de su propio dominio, incluidos los dominios especificados en un archivo de política entre dominios. Es necesario incluir un archivo de política en el servidor de archivos si el archivo SWF que inicia la carga o descarga no procede del mismo dominio que el servidor.

NOTA

 

Sólo se puede realizar una acción browse() o download() cada vez, porque sólo puede abrirse un cuadro de diálogo en cualquier punto.

El script de servidor que gestiona la carga de archivos espera una solicitud HTTP POST con los siguientes elementos:

A continuación se muestra un ejemplo de solicitud HTTP POST:

POST /handler.asp HTTP/1.1
Accept: text/*
Content-Type: multipart/form-data;
boundary=----------Ij5ae0ae0KM7GI3KM7ei4cH2ei4gL6
User-Agent: Shockwave Flash
Host: www.mydomain.com
Content-Length: 421
Connection: Keep-Alive
Cache-Control: no-cache

------------Ij5ae0ae0KM7GI3KM7ei4cH2ei4gL6 
Content-Disposition: form-data; name="Filename"

sushi.jpg 
------------Ij5ae0ae0KM7GI3KM7ei4cH2ei4gL6
Content-Disposition: form-data; name="Filedata"; filename="sushi.jpg"
Content-Type: application/octet-stream

Test File 
------------Ij5ae0ae0KM7GI3KM7ei4cH2ei4gL6
Content-Disposition: form-data; name="Upload"

Submit Query
------------Ij5ae0ae0KM7GI3KM7ei4cH2ei4gL6
(actual file data,,,)

La siguiente solicitud HTTP POST de ejemplo envía tres variables POST: api_sig, api_key y auth_token, y utiliza "photo" como valor en el nombre del campo de datos de carga personalizado:

POST /handler.asp HTTP/1.1
Accept: text/*
Content-Type: multipart/form-data;
boundary=----------Ij5ae0ae0KM7GI3KM7ei4cH2ei4gL6
User-Agent: Shockwave Flash
Host: www.mydomain.com
Content-Length: 421
Connection: Keep-Alive
Cache-Control: no-cache

------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="Filename"

sushi.jpg
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="api_sig"

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="api_key"

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="auth_token"

XXXXXXXXXXXXXXXXXXXXXXX
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="photo"; filename="sushi.jpg"
Content-Type: application/octet-stream

(actual file data,,,)
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="Upload"

Submit Query
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7--

Carga de archivos en un servidor

Para cargar archivos en un servidor, hay que llamar primero al método browse() para permitir que un usuario seleccione uno o varios archivos. A continuación, cuando se llama al método FileReference.upload(), el archivo seleccionado se transfiere al servidor. Si el usuario ha seleccionado varios archivos con el método FileReferenceList.browse(), Flash Player crea una matriz de archivos seleccionados denominada FileReferenceList.fileList. A continuación, se puede utilizar el método FileReference.upload() para cargar cada archivo de forma individual.

NOTA

 

La utilización del método FileReference.browse() permite cargar únicamente archivos individuales. Para permitir que un usuario cargue varios archivos, es necesario utilizar el método FileReferenceList.browse().

De forma predeterminada, el cuadro de diálogo del selector de archivos del sistema permite a los usuarios seleccionar cualquier tipo de archivo del equipo local, aunque los desarrolladores pueden especificar uno o varios filtros personalizados de tipo de archivo. Para ello, deben utilizar la clase FileFilter y pasar una matriz de instancias de filtro de archivos al método browse():

var imageTypes:FileFilter = new FileFilter("Images (*.jpg, *.jpeg, *.gif, *.png)", "*.jpg; *.jpeg; *.gif; *.png");
var textTypes:FileFilter = new FileFilter("Text Files (*.txt, *.rtf)", "*.txt; *.rtf");
var allTypes:Array = new Array(imageTypes, textTypes);
var fileRef:FileReference = new FileReference();
fileRef.browse(allTypes);

Cuando el usuario ha seleccionado los archivos y ha hecho clic en el botón Abrir en el selector de archivos del sistema, se distribuye el evento Event.SELECT. Si se ha utilizado el método FileReference.browse() para seleccionar un archivo para cargarlo, es necesario utilizar el siguiente código para enviar el archivo a un servidor Web:

var fileRef:FileReference = new FileReference();
fileRef.addEventListener(Event.SELECT, selectHandler);
fileRef.addEventListener(Event.COMPLETE, completeHandler);
try
{
    var success:Boolean = fileRef.browse();
}
catch (error:Error)
{
    trace("Unable to browse for files.");
}
function selectHandler(event:Event):void
{
    var request:URLRequest = new URLRequest("http://www.[yourdomain].com/fileUploadScript.cfm")
    try
    {
        fileRef.upload(request);
    }
    catch (error:Error)
    {
        trace("Unable to upload file.");
    }
}
function completeHandler(event:Event):void
{
    trace("uploaded");
}

SUGERENCIA

 

Para enviar datos al servidor con el método FileReference.upload(), se pueden utilizar las propiedades URLRequest.method y URLRequest.data para enviar variables con los métodos POST o GET.

Cuando se intenta cargar un archivo con el método FileReference.upload(), se puede distribuir cualquiera de los siguientes eventos:

SUGERENCIA

 

Flash Player no ofrece compatibilidad total con los servidores que requieren autenticación. Sólo los archivos SWF que se ejecutan en un navegador, es decir, que emplean el plug-in de navegador o un control Microsoft ActiveX®, pueden mostrar un cuadro de diálogo para pedir al usuario que introduzca un nombre de usuario y una contraseña para la autenticación y, además, sólo para descargas. La transferencia de archivos no se producirá correctamente en las cargas que utilicen el plug-in o el control ActiveX, o en las cargas y descargas que utilicen el reproductor autónomo o externo.

Si se crea un script de servidor en ColdFusion para aceptar una carga de archivos desde Flash Player, se puede utilizar un código similar al siguiente:

<cffile action="upload" filefield="Filedata" destination="#ExpandPath('./')#" nameconflict="OVERWRITE" />

Este código de ColdFusion carga el archivo enviado por Flash Player y lo guarda en el mismo directorio que la plantilla de ColdFusion, sobrescribiendo cualquier archivo con el mismo nombre. El código anterior muestra la cantidad mínima de código necesario para aceptar una carga de archivos; este script no debería utilizarse en un entorno de producción. Lo ideal sería añadir validación de datos para garantizar que los usuarios sólo cargan tipos de archivos aceptados como, por ejemplo, una imagen, en lugar de un script de servidor potencialmente peligroso.

El siguiente código muestra cargas de archivos mediante PHP e incluye validación de datos. El script limita en 10 el número de archivos cargados en el directorio de carga, garantiza que el tamaño de archivo es inferior a 200 KB, y sólo permite cargar y guardar archivos JPEG, GIF o PNG en el sistema de archivos.

<?php
$MAXIMUM_FILESIZE = 1024 * 200; // 200KB
$MAXIMUM_FILE_COUNT = 10; // keep maximum 10 files on server
echo exif_imagetype($_FILES['Filedata']);
if ($_FILES['Filedata']['size'] <= $MAXIMUM_FILESIZE)
{
    move_uploaded_file($_FILES['Filedata']['tmp_name'], "./temporary/".$_FILES['Filedata']['name']);
    $type = exif_imagetype("./temporary/".$_FILES['Filedata']['name']);
    if ($type == 1 || $type == 2 || $type == 3)
    {
        rename("./temporary/".$_FILES['Filedata']['name'], "./images/".$_FILES['Filedata']['name']);
    }
    else
    {
        unlink("./temporary/".$_FILES['Filedata']['name']);
    }
}
$directory = opendir('./images/');
$files = array();
while ($file = readdir($directory))
{
    array_push($files, array('./images/'.$file, filectime('./images/'.$file)));
}
usort($files, sorter);
if (count($files) > $MAXIMUM_FILE_COUNT)
{
    $files_to_delete = array_splice($files, 0, count($files) - $MAXIMUM_FILE_COUNT);
    for ($i = 0; $i < count($files_to_delete); $i++)
    {
        unlink($files_to_delete[$i][0]);
    }
}
print_r($files);
closedir($directory);

function sorter($a, $b)
{
    if ($a[1] == $b[1])
    {
        return 0;
    }
    else
    {
        return ($a[1] < $b[1]) ? -1 : 1;
    }
}
?>

Se pueden pasar variables adicionales al script de carga mediante el método de solicitud POST o GET. Para enviar variables adicionales de POST al script de carga, se puede utilizar el siguiente código:

var fileRef:FileReference = new FileReference();
fileRef.addEventListener(Event.SELECT, selectHandler);
fileRef.addEventListener(Event.COMPLETE, completeHandler);
fileRef.browse();
function selectHandler(event:Event):void
{
    var params:URLVariables = new URLVariables();
    params.date = new Date();
    params.ssid = "94103-1394-2345";
    var request:URLRequest = new URLRequest("http://www.yourdomain.com/FileReferenceUpload/fileupload.cfm");
    request.method = URLRequestMethod.POST;
    request.data = params;
    fileRef.upload(request, "Custom1");
}
function completeHandler(event:Event):void
{
    trace("uploaded");
}

El ejemplo anterior crea un nuevo objeto URLVariables que se pasa al script del servidor remoto. En versiones anteriores de ActionScript, se podían pasar variables al script de carga del servidor pasando valores en la cadena de consulta. ActionScript 3.0 permite pasar variables al script remoto con un objeto URLRequest, que permite pasar datos mediante el método POST o GET que, a su vez, hace más sencillo pasar grandes conjuntos de datos. Para especificar si las variables se pasan con el método de solicitud GET o POST, se puede establecer la propiedad URLRequest.method en URLRequestMethod.GET o URLRequestMethod.POST, respectivamente.

ActionScript 3.0 también permite sustituir el nombre del campo de archivo de carga predeterminado, Filedata, proporcionando un segundo parámetro al método upload(), como se muestra en el ejemplo anterior (que sustituía el valor predeterminado Filedata por Custom1).

De forma predeterminada, Flash Player no intentará enviar una carga de prueba. Para sustituir este comportamiento, se puede pasar el valor true como tercer parámetro al método upload(). El objetivo de la carga de prueba es comprobar si la carga de archivos real se realizará correctamente, así como la autenticación del servidor, en caso de ser necesaria.

NOTA

 

Actualmente, la carga de prueba sólo puede realizarse en Flash Player basado en Windows.

Descarga de archivos de un servidor

Para permitir que los usuarios descarguen archivos de un servidor, se utiliza el método FileReference.download(), que utiliza dos parámetros: request y defaultFileName. El primer parámetro es el objeto URLRequest que contiene el URL del archivo para descargar. El segundo parámetro es opcional y permite especificar un nombre de archivo predeterminado que aparece en el cuadro de diálogo del archivo descargado. Si se omite el segundo parámetro, defaultFileName, se utiliza el nombre de archivo del URL especificado.

El siguiente código descarga un archivo denominado index.xml desde el mismo directorio que el documento SWF:

var request:URLRequest = new URLRequest("index.xml");
var fileRef:FileReference = new FileReference();
fileRef.download(request);

Para establecer currentnews.xml como nombre predeterminado, en lugar de index.xml, es necesario especificar el parámetro defaultFileName, como se muestra en el siguiente fragmento de código:

var request:URLRequest = new URLRequest("index.xml");
var fileToDownload:FileReference = new FileReference();
fileToDownload.download(request, "currentnews.xml");

Cambiar el nombre de un archivo puede ser muy útil si el nombre de archivo del servidor no es intuitivo o ha sido generado por el servidor. También se recomienda especificar de forma explícita el parámetro defaultFileName cuando se descarga un archivo mediante un script de servidor, en lugar de descargarlo directamente. Por ejemplo, es necesario especificar el parámetro defaultFileName si se dispone de un script de servidor que descarga archivos específicos en función de las variables de URL que se le pasan. De lo contrario, el nombre predeterminado del archivo descargado es el nombre del script de servidor.

Es posible enviar datos al servidor mediante el método download() añadiendo parámetros al URL, para que los analice el script de servidor. El siguiente fragmento de código ActionScript 3.0 descarga un documento en función de los parámetros pasados a un script de ColdFusion:

package
{
    import flash.display.Sprite;
    import flash.net.FileReference;
    import flash.net.URLRequest;
    import flash.net.URLRequestMethod;
    import flash.net.URLVariables;

    public class DownloadFileExample extends Sprite
    {
        private var fileToDownload:FileReference;
        public function DownloadFileExample()
        {
            var request:URLRequest = new URLRequest();
            request.url = "http://www.[yourdomain].com/downloadfile.cfm";
            request.method = URLRequestMethod.GET;
            request.data = new URLVariables("id=2");
            fileToDownload = new FileReference();
            try
            {
                fileToDownload.download(request, "file2.txt");
            }
            catch (error:Error)
            {
                trace("Unable to download file.");
            }
        }
    }
}

El siguiente código muestra el script ColdFusion, download.cfm, que descarga uno de los dos archivos del servidor, dependiendo del valor de una variable de URL:

<cfparam name="URL.id" default="1" />
<cfswitch expression="#URL.id#">
    <cfcase value="2">
        <cfcontent type="text/plain" file="#ExpandPath('two.txt')#" deletefile="No" />
    </cfcase>
    <cfdefaultcase>
        <cfcontent type="text/plain" file="#ExpandPath('one.txt')#" deletefile="No" />
    </cfdefaultcase>
</cfswitch>

Clase FileReferenceList

La clase FileReferenceList permite al usuario seleccionar uno o varios archivos para cargarlos en un script de servidor. La carga de archivos se controla mediante el método FileReference.upload(), al que es necesario llamar en cada archivo que selecciona el usuario.

El siguiente código crea dos objetos FileFilter (imageFilter y textFilter) y los pasa en una matriz al método FileReferenceList.browse(). Como consecuencia, el cuadro de diálogo del archivo del sistema operativo muestra dos filtros de tipos de archivo posibles.

var imageFilter:FileFilter = new FileFilter("Image Files (*.jpg, *.jpeg, *.gif, *.png)", "*.jpg; *.jpeg; *.gif; *.png");
var textFilter:FileFilter = new FileFilter("Text Files (*.txt, *.rtf)", "*.txt; *.rtf");
var fileRefList:FileReferenceList = new FileReferenceList();
try
{
    var success:Boolean = fileRefList.browse(new Array(imageFilter, textFilter));
}
catch (error:Error) 
{
    trace("Unable to browse for files.");
}

Permitir al usuario seleccionar y cargar uno o varios archivos mediante la clase FileReferenceList equivale a utilizar FileReference.browse() para seleccionar archivos, aunque FileReferenceList permite seleccionar más de un archivo. Para cargar varios archivos es necesario actualizar cada uno de los archivos seleccionados mediante FileReference.upload(), como se muestra en el siguiente código:

var fileRefList:FileReferenceList = new FileReferenceList();
fileRefList.addEventListener(Event.SELECT, selectHandler);
fileRefList.browse();

function selectHandler(event:Event):void
{
    var request:URLRequest = new URLRequest("http://www.[yourdomain].com/fileUploadScript.cfm");
    var file:FileReference;
    var files:FileReferenceList = FileReferenceList(event.target);
    var selectedFileArray:Array = files.fileList;
    for (var i:uint = 0; i < selectedFileArray.length; i++)
    {
        file = FileReference(selectedFileArray[i]);
        file.addEventListener(Event.COMPLETE, completeHandler);
        try
        {
            file.upload(request);
        }
        catch (error:Error)
        {
            trace("Unable to upload files.");
        }
    }
}
function completeHandler(event:Event):void
{
    trace("uploaded");
}

Dado que el evento Event.COMPLETE se añade a cada objeto FileReference individual de la matriz, Flash Player llama al método completeHandler() cuando finaliza la carga de cada uno de los archivos.


Flash CS3

 

Enviarme un mensaje de correo electrónico cuando se añadan comentarios a esta página | Informe de comentarios

Página actual: http://livedocs.adobe.com/flash/9.0_es/main/00000320.html