Como baixar um arquivo (HTML)

[ Este artigo destina-se aos desenvolvedores do Windows 8.x e do Windows Phone 8.x que escrevem aplicativos do Windows Runtime. Se você estiver desenvolvendo para o Windows 10, consulte documentação mais recente]

Este tópico mostrará a você como baixar um arquivo.

Os aplicativos podem usar as APIs abordadas neste tópico para habilitar a interação com os serviços Web, para consumir ou compartilhar formatos de mídia populares, como fotos, música e vídeo.

O desenvolvimento de um aplicativo em JavaScript envolve duas opções principais para solicitação de arquivos em locais na Internet. Arquivos pequenos, como os ativos que são recuperados com frequência, podem ser baixados por meio de XHR, para tornar assíncrona a solicitação HTTP GET. Essa função encapsula uma chamada XMLHttpRequest em uma promessa, o padrão de programação que permite um comportamento assíncrono em JavaScript.

Alternativamente, para fornecer uma experiência consistente ao baixar mídia grande (vídeo e música) com um tempo de vida operacional que pode ultrapassar as várias suspensões do aplicativo e/ou mudanças na disponibilidade da rede, seu aplicativo pode usar a Background Transfer. Para obter uma aparência de alto nível em Transferência em Segundo Plano, consulte Transferindo dados em segundo plano.

Pré-requisitos

Para obter instruções sobre a criação de um aplicativo em JavaScript , consulte Criar seu primeiro aplicativo do Tempo de Execução do Windows em JavaScript. Além disso, as promessas de JavaScript são usadas neste tópico para concluir as operações assíncronas. Para obter mais informações sobre esse padrão de programação, consulte Programação assíncrona em JavaScript usando promessas.

Para garantir que seu aplicativo está pronto para a rede, defina a capacidade no arquivo Package.appxmanifest do projeto. Para obter uma definição de cada recurso de rede, veja Como configurar recursos de isolamento de rede.

Todos os exemplos de Transferência em Segundo Plano neste tópico se baseiam no Exemplo de Transferência em Segundo Plano.

Baixando um arquivo usando XHR

Para iniciar uma solicitação básica assíncrona de HTTP usando JavaScript, chame o XHR e forneça os dados de solicitação relevantes usando o parâmetro Option. Por padrão, essa chamada de método é uma solicitação GET, portanto os únicos valores exigidos e fornecidos por Option são a URL e o responseType. No entanto, muitos serviços da Web requerem autenticação, e essas credenciais devem ser incluídas ao chamar XHR para solicitar recursos de qualquer serviço seguro da Web.

Uma operação GET XHR também exige que o tipo de conteúdo esperado na resposta seja especificado usando o responseType no parâmetro Option. No nosso exemplo, foi solicitado um arquivo .png, então o nosso valor responseType é "blob". Para obter uma lista completa de tipos de conteúdo suportados e exemplos de como solicitá-los, consulte Como baixar um arquivo com WinJS xhr.


WinJS.xhr({ url: "https://www.microsoft.com/windows/Framework/images/win_logo.png", responseType: "blob" })
    .done(
        function (request) {
            var imageBlob = URL.createObjectURL(request.response);
            var imageTag = xhrDiv.appendChild(document.createElement("image"));
      imageTag.src = imageBlob;
     });

No JavaScript, cada promessa têm duas funções que você pode usar para manipular os resultados de uma operação assíncrona: then e done. As duas funções usam três parâmetros: uma função que é chamada quando o download é concluído (isto é, quando readyState for 4), uma função que é chamada quando há um erro e uma função que é chamada enquanto o download está em andamento (quando readyState for 2 ou 3). Somente a função done lança uma exceção se um erro não for manipulado. Esta função é preferencial quando uma função error não é fornecida.

Baixando um arquivo usando a Transferência em Tela de Fundo

Na Transferência em Segundo Plano, cada download existe como um DownloadOperation que expõe vários métodos de controle usados para pausar, retomar, reiniciar e cancelar a operação. Os eventos de aplicativo (por exemplo, suspensão ou encerramento) e as alterações de conectividade são manipulados automaticamente pelo sistema por DownloadOperation; os downloads continuarão durante os períodos de suspensão do aplicativo ou serão pausados e persistirão após o encerramento do aplicativo. Para cenários de rede móvel, a configuração da propriedade CostPolicy indicará se o aplicativo tentará ou não começar ou continuar downloads enquanto uma rede limitada está sendo usada para conectividade com a Internet.

Os exemplos a seguir orientarão você na criação e inicialização de um download básico e mostrarão como enumerar e reintroduzir operações que persistiram desde a sessão anterior do aplicativo.

Hh700370.wedge(pt-br,WIN.10).gifConfigurar e iniciar um download de arquivo de Transferência de Tela de Fundo

  • O seguinte exemplo demonstra como as cadeias de caracteres representando um URI e um nome de arquivo podem ser usadas para criar um objeto Uri e o StorageFile que conterá o arquivo solicitado. Nesse exemplo, o novo arquivo é colocado automaticamente em um local predefinido. Como alternativa, o FileSavePicker pode ser usado para permitir que os usuários indiquem onde salvar o arquivo no dispositivo. Observe que o método load chamado para reatribuir retornos de chamada para DownloadOperation, se persistir após o encerramento do aplicativo, estará na classe DownloadOp, definida posteriormente nesta seção.

    function DownloadOp() {
        var download = null;
        var promise = null;
        var imageStream = null;
    
        this.start = function (uriString, fileName) {
            try {
                // Asynchronously create the file in the pictures folder.
                Windows.Storage.KnownFolders.picturesLibrary.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.generateUniqueName).done(function (newFile) {
                    var uri = Windows.Foundation.Uri(uriString);
                    var downloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();
    
                    // Create a new download operation.
                    download = downloader.createDownload(uri, newFile);
    
                    // Start the download and persist the promise to be able to cancel the download.
                    promise = download.startAsync().then(complete, error, progress);
                }, error);
            } catch (err) {
                displayException(err);
            }
        };
        // On application activation, reassign callbacks for a download
        // operation persisted from previous application state.
        this.load = function (loadedDownload) {
            try {
                download = loadedDownload;
                printLog("Found download: " + download.guid + " from previous application run.<br\>");
                promise = download.attachAsync().then(complete, error, progress);
            } catch (err) {
                displayException(err);
            }
        };
    }
    

    Observe as chamadas de método assíncrono definidas usando promessas de JavaScript. Examine a linha 17 do exemplo de código anterior:

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

    A chamada de método assíncrono é seguida por uma instrução then que indica métodos, definidos pelo aplicativo, que são chamados quando é retornado um resultado da chamada de método assíncrono. Para obter mais informações sobre esse padrão de programação, consulte Programação assíncrona em JavaScript usando promessas.

Hh700370.wedge(pt-br,WIN.10).gifAdicionando outros métodos de controle de operação

  • O nível de controle pode ser aumentado ao implementar métodos DownloadOperation adicionais. Por exemplo, adicionar o seguinte código ao exemplo acima introduzirá a capacidade de cancelar o download.

    // Cancel download.
    this.cancel = function () {
        try {
            if (promise) {
                promise.cancel();
                promise = null;
                printLog("Canceling download: " + download.guid + "<br\>");
                if (imageStream) {
                    imageStream.close();
                }
            }
            else {
                printLog("Download " + download.guid + " already canceled.<br\>");
            }
        } catch (err) {
            displayException(err);
        }
    };
    

Na conclusão ou no cancelamento de uma DownloadOperation, todos os recursos de sistema associados são liberados. Entretanto, se o aplicativo for encerrado antes que qualquer desses eventos ocorra, os downloads serão pausados e persistirão no segundo plano. Os exemplos a seguir demonstram como reintroduzir downloads persistentes em uma nova sessão de aplicativo.

Hh700370.wedge(pt-br,WIN.10).gifEnumerar operações persistentes na inicialização

  1. Antes de definir a função que enumera operações persistidas, é nós precisamos criar uma matriz que conterá os objetos DownloadOperation que ela retornará:

    var downloadOps = [];
    
  2. Depois, nós definimos a função que enumera operações persistentes e as armazena em nossa matriz. Observe que o método load chamado para reatribuir retornos de chamada para um DownloadOperation persistente está no exemplo de DownloadOp que definimos posteriormente nesta seção.

    // Enumerate outstanding downloads.
    Windows.Networking.BackgroundTransfer.BackgroundDownloader.getCurrentDownloadsAsync().done(function (downloads) {
    
        for (var i = 0; i < downloads.size; i++) {
            var download = new DownloadOp();
            download.load(downloads[i]);
            downloadOps.push(download);
        }
    });
    

    Observação  

    Para os aplicativos da Loja do Windows Phone, as transferências em segundo plano continuam a progredir enquanto seu aplicativo não está em primeiro plano. Como seu aplicativo não está em execução nesse cenário, ele não receberá uma notificação quando a transferência for concluída. Quando seu aplicativo for retomado, se você verificar o progresso de uma transferência concluída, o status será BackgroundTransferStatus.Running. No entanto, quando você anexar à transferência como no código de exemplo acima, o manipulador de conclusão da tarefa será gerado e o status de transferência será atualizado.

Tempos limite de solicitação

Existem dois cenários principais de tempo limite de conexão para levar em consideração.

  • Ao estabelecer uma nova conexão para a transferência, a solicitação da conexão é anulada se não é estabelecida dentro de cinco minutos.

  • Depois de uma conexão ser estabelecida, uma mensagem de solicitação de HTTP que não tenha recebido uma resposta em dois minutos será anulada.

Em qualquer cenário, supondo que haja conectividade com a Internet, a Transferência de Segundo Plano repetirá automaticamente a solicitação no máximo três vezes. Caso a conectividade com a Internet não seja detectada, outras solicitações esperarão até que a conexão seja estabelecida.

Para operações XHR, valores específicos de tempo limite podem ser definidos com a propriedade WinJS.Promise.timeout. Para saber mais sobre como isso é feito, veja Definindo os valores de tempo limite com WinJS.xhr.

Instrução de depuração

Parar uma sessão de depuração no Microsoft Visual Studio é semelhante a fechar seu aplicativo. Mesmo durante a depuração, seu aplicativo deve enumerar e então retomar, reinicie ou cancelar quaisquer downloads que persista da sessão anterior. Por exemplo, você pode fazer com que seu aplicativo cancele as operações de download enumeradas e existentes na inicialização do aplicativo se não houver interesse nas operações anteriores para a sessão de depuração atual.

Se houver atualizações de projeto do Visual Studio, como alterações no manifesto do aplicativo, e o aplicativo tiver sido desinstalado e reimplantado, o GetCurrentUploadsAsync não poderá enumerar operações criadas usando a implantação de aplicativo anterior.

Consulte Depurando e testando aplicativos da Windows Store para obter mais informações.

Quando usar a Transferência em segundo plano durante o desenvolvimento, pode acontecer que os caches internos das operações de transferência ativas e concluídas poderão sair da sincronização. Isso pode resultar na incapacidade de iniciar novas operações de transferência ou de interagir com as operações existentes e objetos do BackgroundTransferGroup. Em alguns casos, a tentativa de interagir com operações existentes pode gerar uma falha. Isso pode ocorrer se a propriedade TransferBehavior estiver definida para Parallel. Esse problema ocorre somente em determinados cenários, durante o desenvolvimento, e não se aplica a usuários finais de seu aplicativo.

Quatro cenários usando o Visual Studio podem causar esse problema.

  • Você pode criar um novo projeto com o mesmo nome de aplicativo de um projeto existente, mas em uma linguagem diferente (de C++ para C#, por exemplo).
  • Você pode alterar a arquitetura de destino (de x86 para x64, por exemplo) em um projeto existente.
  • Você pode alterar a cultura (de neutra para en-US, por exemplo) em um projeto existente.
  • Você pode adicionar ou remover um recurso no manifesto do pacote (adicionando Autenticação Empresarial, por exemplo) em um projeto existente.

Aplicativos comuns em serviço, incluindo atualizações de manifesto, que adicionam ou removem recursos, não geram esse problema nas implantações de usuário final para seu aplicativos.

Para contornar esse problema, desinstale completamente todas as versões do aplicativo e reimplante com a nova linguagem, arquitetura, cultura ou recurso. Isso pode ser feito por meio da tela Iniciar ou usando PowerShell e o cmdlet Remove-AppxPackage.

Resumo e próximas etapas

Neste tópico, revisamos como baixar arquivos usando as APIs Background Transfer em JavaScript. Revimos as diferenças entre as duas e enfatizamos como a praticidade do aplicativo depende do tamanho e do tempo de vida de uma transferência de arquivo.

Também é possível usar XHR e Transferência em Segundo Plano para carregar arquivos. Para ver uma explicação sobre os conceitos fundamentais e exemplos, consulte Como carregar um arquivo.

Tópicos relacionados

Outro

Programação assíncrona em JavaScript com promessas

Criar seu primeiro aplicativo do Tempo de Execução do Windows em JavaScript

Como configurar recursos de rede

Como baixar um arquivo com WinJS xhr

Como carregar um arquivo

Referência

HttpClient

Windows.Networking.BackgroundTransfer

WinJS.XHR

Exemplos

Exemplo de transferência em segundo plano

Exemplo de HttpClient