Cómo cargar un archivo (HTML)

[ Este artículo está destinado a desarrolladores de Windows 8.x y Windows Phone 8.x que escriben aplicaciones de Windows en tiempo de ejecución. Si estás desarrollando para Windows 10, consulta la documentación más reciente

Este tema mostrará cómo cargar datos o un archivo de un dispositivo a Internet.

Las aplicaciones pueden usar las API analizadas en este tema para permitir la interacción de las aplicaciones con servicios web a fin de consumir o compartir formatos multimedia populares, como fotos, música y vídeo.

Tu aplicación puede usar Background Transfer para transferencias de secuencias, de varias partes o de gran tamaño (vídeo, música e imágenes grandes), con una duración operativa que puede extenderse más allá de múltiples suspensiones de la aplicación o cambios en la disponibilidad de la red.

Para echar un vistazo general a la transferencia en segundo plano, consulta el tema Transferencia de datos en segundo plano.

Requisitos previos

Si necesitas ayuda para crear una aplicación de la Tienda Windows de JavaScript, consulta Crear la primera aplicación de Windows en tiempo de ejecución con JavaScript. De forma adicional, en este tema se usan promesas de JavaScript para completar las operaciones asincrónicas. Si quieres más información acerca de este patrón de programación, consulta Programación asincrónica en JavaScript con compromisos.

Para asegurarte de que la aplicación está lista para la red, debes establecer la capacidad en el archivo Package.appxmanifest del proyecto. Para obtener una definición de cada funcionalidad de red, consulta Cómo configurar funcionalidades de aislamiento de red.

Los siguientes ejemplos de transferencia en segundo plano usan JavaScript y se basan en la muestra de transferencia en segundo plano.

Operaciones de carga de transferencia en segundo plano

Al usar la transferencia en segundo plano, la carga existe como una UploadOperation que expone varios métodos de control que se usan para reiniciar o cancelar la operación. El sistema controla automáticamente los eventos de la aplicación (por ejemplo, suspensión o finalización) y los cambios en la conectividad por UploadOperation; las cargas continuarán durante los periodos de suspensión o pausa de la aplicación y se mantendrán tras la finalización de la misma. Además, al establecer la propiedad CostPolicy, se indica si tu aplicación iniciará las cargas mientras se usa una red de uso medido para la conexión a Internet.

En los siguientes ejemplos, te explicaremos cómo crear e inicializar una carga básica y cómo enumerar y volver a introducir operaciones persistentes de una sesión anterior de la aplicación.

Cargar un archivo

La creación de una carga comienza con BackgroundUploader. Esta clase se usa para proporcionar los métodos que permiten a tu aplicación configurar la carga antes de crear la UploadOperation resultante. En el siguiente ejemplo se muestra cómo realizar esto con los objetos Uri y StorageFile necesarios.

  1. Identificar el archivo y el destino de la carga

    Antes de comenzar la creación de una UploadOperation, debemos identificar el URI de la ubicación en la que se va a realizar la carga y el archivo que se cargará. En el siguiente ejemplo, el valor uriString se rellena mediante una cadena de entrada de UI y el valor file mediante el objeto StorageFile devuelto por una operación PickSingleFileAsync.

    function uploadFile() {
        var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
        filePicker.fileTypeFilter.replaceAll(["*"]);
    
        filePicker.pickSingleFileAsync().then(function (file) {
            if (!file) {
                printLog("No file selected");
                return;
            }
    
            var upload = new UploadOp();
            var uriString = document.getElementById("serverAddressField").value;
            upload.start(uriString, file);
    
            // Store the upload operation in the uploadOps array.
            uploadOperations.push(upload);
        });
    }
    
  2. Crear e inicializar la operación de carga

    En el paso anterior, los valores uriString y file se pasan a una instancia de nuestro siguiente ejemplo, UploadOp, donde se usan para configurar e iniciar la nueva operación de carga. Primero, uriString se analiza para crear el objeto Uri necesario.

    Después, BackgroundUploader usa las propiedades del StorageFile proporcionado (file) para rellenar el encabezado de la solicitud y establecer la propiedad SourceFile con el objeto StorageFile. Después se llama al método SetRequestHeader para insertar el nombre de archivo, indicado como una cadena, y la propiedad StorageFile.Name.

    Finalmente, BackgroundUploader crea la UploadOperation (upload).

    function UploadOp() {
        var upload = null;
        var promise = null;
    
        this.start = function (uriString, file) {
            try {
    
                var uri = new Windows.Foundation.Uri(uriString);
                var uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();
    
                // Set a header, so the server can save the file (this is specific to the sample server).
                uploader.setRequestHeader("Filename", file.name);
    
                // Create a new upload operation.
                upload = uploader.createUpload(uri, file);
    
                // Start the upload and persist the promise to be able to cancel the upload.
                promise = upload.startAsync().then(complete, error, progress);
            } catch (err) {
                displayError(err);
            }
        };
        // On application activation, reassign callbacks for a upload
        // operation persisted from previous application state.
        this.load = function (loadedUpload) {
            try {
                upload = loadedUpload;
                promise = upload.attachAsync().then(complete, error, progress);
            } catch (err) {
                displayError(err);
            }
        };
    }
    

    Observa las llamadas de método asincrónico definidas con promesas de JavaScript. En una línea del último ejemplo:

    promise = upload.startAsync().then(complete, error, progress);
    

    La llamada de método asincrónico está seguida por una instrucción then que indica métodos definidos por la aplicación a los que se llama cuando se devuelve un resultado de la llamada de método asincrónico. Si quieres obtener más información acerca de este patrón de programación, consulta el tema sobre programación asincrónica en JavaScript con compromisos.

Cargar varios archivos

  1. Identificar los archivos y el destino de la carga

    En un escenario que implica varios archivos transferidos con una sola UploadOperation, el proceso comienza como lo hace normalmente, proporcionando primero el URI de destino requerido y la información del archivo local. Al igual que en el ejemplo de la sección anterior, el usuario final proporciona el URI como una cadena y FileOpenPicker se puede usar para ofrecer la capacidad de indicar archivos en la interfaz de usuario. Sin embargo, en este escenario la aplicación debería llamar en cambio al método PickMultipleFilesAsync para permitir la selección de varios archivos en la interfaz de usuario.

    
    function uploadFiles() {
       var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
       filePicker.fileTypeFilter.replaceAll(["*"]);
    
       filePicker.pickMultipleFilesAsync().then(function (files) {
          if (files === 0) {
             printLog("No file selected");
                return;
          }
    
          var upload = new UploadOperation();
          var uriString = document.getElementById("serverAddressField").value;
          upload.startMultipart(uriString, files);
    
          // Persist the upload operation in the global array.
          uploadOperations.push(upload);
       });
    }
    
  2. Crear objetos para los parámetros proporcionados

    Los siguientes dos ejemplos usan código contenido en un solo método de ejemplo, startMultipart, al que se llamó al final del último paso. A fines de instrucción, el código del método que crea una matriz de objetos BackgroundTransferContentPart se ha separado del código que crea la UploadOperation resultante.

    Primero, la cadena de URI proporcionada por el usuario se inicializa como Uri. Después se itera la matriz de objetos IStorageFile (files) pasada a este método y se usa cada objeto para crear un nuevo objeto BackgroundTransferContentPart, que después se coloca en la matriz contentParts.

    
    upload.startMultipart = function (uriString, files) {
        try {
            var uri = new Windows.Foundation.Uri(uriString);
            var uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();
    
            var contentParts = [];
            files.forEach(function (file, index) {
                var part = new Windows.Networking.BackgroundTransfer.BackgroundTransferContentPart("File" + index, file.name);
                part.setFile(file);
                contentParts.push(part);
            });
    
  3. Crear e inicializar la operación de carga de varias partes

    Con nuestra matriz contentParts compuesta por todos los objetos BackgroundTransferContentPart representando cada IStorageFile para cargar, estamos listos para llamar a CreateUploadAsync con Uri para indicar adónde se enviará la solicitud.

            // Create a new upload operation.
            uploader.createUploadAsync(uri, contentParts).then(function (uploadOperation) {
    
               // Start the upload and persist the promise to be able to cancel the upload.
               upload = uploadOperation;
               promise = uploadOperation.startAsync().then(complete, error, progress);
            });
    
         } catch (err) {
             displayError(err);
         }
     };
    

Enumerar operaciones persistentes en el inicio

Después de finalizada o cancelada una UploadOperation, se liberan todos los recursos del sistema asociados a ella. Sin embargo, si tu aplicación finaliza antes de que sucedan algunas de estas situaciones, se pausan todas las operaciones activas y se mantienen ocupados los recursos asociados a ellas. Si no se enumeran estas operaciones y se vuelven a introducir en la siguiente sesión de la aplicación, no se completarán y seguirán ocupando recursos del dispositivo.

  1. Antes de definir la función que enumera las operaciones persistentes, necesitamos crear una matriz que contenga los objetos UploadOperation que va a devolver:

    var uploadOperations = [];
    
  2. Después definimos la función que enumera las operaciones persistidas y las almacena en nuestra matriz. Ten en cuenta que el método load al que se llamó para reasignar las devoluciones de llamada a la UploadOperation, si es que persiste tras la finalización de la aplicación, se encuentra en la clase UploadOp que definiremos más adelante en esta sección.

    function Windows.Networking.BackgroundTransfer.BackgroundUploader.getCurrentUploadsAsync() {
        .then(function (uploads) {
            for (var i = 0; i < uploads.size; i++) {
                var upload = new UploadOp();
                upload.load(uploads[i]);
                uploadOperations.push(upload);
            }
        }
    };
    

    Nota  

    En las aplicaciones de la Tienda de Windows Phone, las transferencias en segundo plano siguen su curso mientras la aplicación no está en primer plano. Dado que la aplicación no se está ejecutando en este escenario, no recibirá una notificación cuando la transferencia finalice. Cuando la aplicación se reanude, si consultas el progreso de la transferencia completada, verás que el estado es BackgroundTransferStatus.Running. No obstante, si anexas controladores a la transferencia como en el ejemplo de código anterior, se activará controlador de finalización de la tarea y el estado de la transferencia será actualizado.

Tiempos de espera de solicitudes

Son dos los escenarios principales relacionados con el tiempo de espera de la conexión que se deben tener en cuenta:

  • Al establecer una nueva conexión para una transferencia, la solicitud de conexión se cancelará si no se establece en cinco minutos.

  • Después de establecer una conexión, se cancelará el mensaje de solicitud HTTP que no haya recibido una respuesta transcurridos dos minutos.

Nota  En ambos escenarios, y suponiendo que hay conexión a Internet, la transferencia en segundo plano intentará una solicitud hasta tres veces de manera automática. Si no se detecta una conexión a Internet, las solicitudes adicionales esperarán hasta que se establezca la conexión.

 

Guía para la depuración

Detener una sesión de depuración en Microsoft Visual Studio se puede comparar a cerrar una aplicación. Las cargas PUT se pausan y las cargas POST se finalizan. Incluso durante la depuración, tu aplicación debe enumerar y reiniciar o cancelar todas las cargas que persisten. Por ejemplo, tu aplicación puede cancelar operaciones de carga persistentes al iniciar la aplicación, si no hay ningún interés por operaciones anteriores para la sesión de depuración.

Mientras se enumeran las cargas y descargas al iniciarse una aplicación durante una sesión de depuración, puedes hacer que tu aplicación las cancele si, en esa sesión de depuración, no se tiene ningún interés por las operaciones anteriores. Ten en cuenta que si hay actualizaciones de proyectos de Visual Studio, como cambios en el manifiesto de la aplicación, y la aplicación se desinstala y se vuelve a instalar, GetCurrentUploadsAsync no podrá enumerar las operaciones creadas con la implementación de aplicación anterior.

Para obtener más información, consulta Depurar y probar aplicaciones de la Tienda Windows.

Cuando uses la transferencia en segundo plano durante el desarrollo, es posible que las memorias caché internas de las operaciones de transferencia activas y finalizadas dejen de estar sincronizadas. Esto puede dar como resultado que no puedas iniciar nuevas operaciones de transferencia o interactuar con operaciones existentes y objetos de BackgroundTransferGroup. En algunos casos, intentar interactuar con operaciones ya existentes puede producir un bloqueo. Este resultado puede producirse si la propiedad TransferBehavior se establece en Parallel. Este problema se produce únicamente en determinados escenarios, durante el desarrollo, y no se aplica a los usuarios finales de tu aplicación.

Cuatro escenarios en los que se usa Visual Studio pueden producir este problema:

  • Creas un proyecto nuevo con el mismo nombre de aplicación que un proyecto ya existente, pero otro lenguaje (de C++ a C#, por ejemplo).
  • Cambias la arquitectura de destino (de x86 a x64, por ejemplo) de un proyecto ya existente.
  • Cambias la cultura (de neutral a en-US, por ejemplo) en un proyecto ya existente.
  • Agregas o quitas una capacidad en el manifiesto del paquete (agregando, por ejemplo, Autenticación de empresa) en un proyecto ya existente.

El mantenimiento regular de tu aplicación, incluidas las actualizaciones de manifiesto que agregan o quitan capacidades, no causa este problema en las implementaciones de usuario final de tu aplicación.

Para evitar este problema, desinstala completamente todas las versiones de la aplicación y vuelve a implementarlas con el nuevo lenguaje, arquitectura, cultura y capacidad. Puedes hacerlo a través de la pantalla Inicio o usando PowerShell y el cmdlet Remove-AppxPackage.

Resumen y siguientes pasos

En este tema hemos revisado cómo cargar archivos mediante las API Background Transfer en JavaScript.

También puedes descargar archivos en tu aplicación de la Tienda Windows. Para ver una explicación de los conceptos básicos y ver ejemplos, consulta Cómo descargar un archivo.

Temas relacionados

Otros

Acceso a la información de conexión y plan de datos

Programación asincrónica en JavaScript con compromisos

Crear la primera aplicación de Windows en tiempo de ejecución con JavaScript

Cómo configurar las funcionalidades de red

Cómo descargar un archivo con WinJS.xhr

Referencia

BackgroundUploader

UploadOperation

Windows.Networking.BackgroundTransfer

Muestras

Muestra de transferencia en segundo plano

Muestra de HttpClient

Cómo descargar un archivo

Windows.Networking.BackgroundTransfer

Muestra de transferencia en segundo plano