Condividi tramite


Come scaricare un file (HTML)

[ Questo articolo è rivolto agli sviluppatori per Windows 8.x e Windows Phone 8.x che realizzano app di Windows Runtime. Gli sviluppatori che usano Windows 10 possono vedere Documentazione aggiornata ]

Questo argomento illustra come scaricare un file

Le app possono avvalersi delle API illustrate in questo argomento per rendere possibile l'interazione con servizi Web che consentono di usare o condividere diffusi formati multimediali per foto, musica e video.

Quando si sviluppa un'app in JavaScript sono disponibili due opzioni principali per richiedere file da posizioni Internet. Piccoli file, come le risorse dei siti recuperate di frequente, possono essere scaricati mediante XHR per effettuare la richiesta HTTP GET asincrona. Questa funzione esegue il wrapping di una chiamata XMLHttpRequest in una promessa, ovvero il modello di programmazione che consente il comportamento asincrono in JavaScript.

In alternativa, per offrire un'esperienza coerente per il download di file di grandi dimensioni (video e musica), con una durata operativa che può estendersi oltre più sospensioni dell'app e/o cambiamenti nella disponibilità di rete, l'app può usare Background Transfer. Per un'analisi più dettagliata del trasferimento in background, vedi Trasferimento di dati in background.

Prerequisiti

Se hai bisogno di aiuto per creare un'app in JavaScript, vedi Creare la prima app di Windows Runtime in JavaScript. Inoltre, in questo argomento si usano promesse JavaScript per completare operazioni asincrone. Per altre informazioni su questo modello di programmazione, vedi Programmazione asincrona in JavaScript con promesse.

Per predisporre la tua app per l'uso in rete, devi impostare la funzionalità nel file Package.appxmanifest del progetto. Per una definizione delle singole funzionalità di rete, vedi Come configurare le funzionalità di isolamento della rete.

Gli esempi della funzionalità Trasferimento in background seguenti si basano sull'esempio di trasferimento in background.

Download di un file con XHR

Per avviare una richiesta HTTP asincrona di base con JavaScript, chiama XHR e fornisci i relativi dati sulla richiesta usando il parametro Option. Per impostazione predefinita, questa chiamata di metodo è una richiesta GET, pertanto gli unici valori richiesti forniti tramite Option sono l'URL e responseType. Molti servizi Web, però, richiedono l'autenticazione, perciò è necessario includere le credenziali quando si chiama XHR per richiedere risorse da qualsiasi servizio Web protetto.

Un'operazione GET XHR richiede inoltre che il tipo di contenuto previsto nella risposta sia specificato tramite l'opzione responseType nel parametro Option. Nel nostro esempio abbiamo richiesto un file con estensione png, perciò il valore di responseType è "blob". Per un elenco completo dei tipi di contenuto supportati ed esempi di come richiederli, vedi Come scaricare un file con 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;
     });

In JavaScript ogni promessa ha due funzioni che puoi usare per gestire i risultati di un'operazione asincrona: then e done. Entrambe le funzioni accettano tre parametri: una funzione chiamata al completamento del download (ovvero quando readyState è 4), una funzione chiamata quando è presente un errore e una funzione chiamata mentre il download è in corso (ovvero quando readyState è 2 o 3). Solo la funzione done genera un'eccezione se un errore non è gestito. Questa funzione è preferibile quando non viene fornita una funzione di errore.

Download di un file con la funzionalità Trasferimento in background

Quando si usa Trasferimento in background, ogni download esiste in forma di DownloadOperation che espone un certo numero di metodi di controllo usati per sospendere, riprendere, riavviare e annullare l'operazione. Gli eventi dell'app (come la sospensione o la chiusura) e i cambiamenti di connettività vengono gestiti automaticamente dal sistema per ogni DownloadOperation. I download continueranno durante i periodi di sospensione dell'app oppure verranno sospesi e saranno persistenti oltre la chiusura dell'app. Per scenari di rete mobile, l'impostazione della proprietà CostPolicy, inoltre, indicherà se l'app tenterà o meno di avviare o continuare download quando per la connettività Internet si usa una rete a consumo.

Negli esempi seguenti viene illustrato come creare e inizializzare un download di base e come enumerare e reintrodurre le operazioni rese persistenti da una sessione precedente dell'app.

Hh700370.wedge(it-it,WIN.10).gifConfigurare e avviare il download di un file con Trasferimento in background

  • L'esempio seguente dimostra come si possono usare le stringhe che rappresentano un URI e un nome di file per creare un oggetto Uri e l'oggetto StorageFile che conterrà la risorsa richiesta. In questo esempio, il nuovo file viene archiviato automaticamente in un posizione predefinita. In alternativa, si può usare FileSavePicker per consentire agli utenti di indicare dove salvare il file nel dispositivo. Nota che il metodo load chiamato per riassegnare i callback a DownloadOperation nel caso debba essere persistente oltre la chiusura dell'app, è nella classe DownloadOp che definiamo più avanti in questa sezione.

    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);
            }
        };
    }
    

    Nota le chiamate di metodo asincrone definite con le promesse JavaScript. Osserviamo la riga 17 dell'esempio di codice precedente:

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

    La chiamata di metodo asincrona è seguita da un'istruzione then che indica i metodi, definiti dall'app, chiamati quando viene restituito un risultato della chiamata di metodo asincrona. Per altre informazioni su questo modello di programmazione, vedi Programmazione asincrona in JavaScript con promesse.

Hh700370.wedge(it-it,WIN.10).gifAggiunta di altri metodi di controllo delle operazioni

  • Si può ottenere un maggiore livello di controllo implementando metodi DownloadOperation aggiuntivi. Ad esempio, aggiungendo il codice seguente all'esempio di sopra si introduce la possibilità di annullare il 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);
        }
    };
    

Durante il completamento o l'annullamento di DownloadOperation vengono rilasciate tutte le eventuali risorse di sistema associate. Se tuttavia l'app viene chiusa prima che si verifichi uno di questi eventi, i download vengono sospesi e resi persistenti in background. Negli esempi seguenti viene illustrato come reintrodurre i download resi persistenti in una nuova sessione dell'app.

Hh700370.wedge(it-it,WIN.10).gifEnumerare le operazioni rese persistenti all'avvio

  1. Prima di definire la funzione che enumera le operazioni persistenti, dobbiamo creare una matrice che conterrà gli oggetti DownloadOperation restituiti:

    var downloadOps = [];
    
  2. Definiamo poi la funzione che enumera le operazioni persistenti e le archivia nella nostra matrice. Nota che il metodo load chiamato per riassegnare i callback a un oggetto DownloadOperation persistente è nell'esempio DownloadOp che definiamo più avanti in questa sezione.

    // 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);
        }
    });
    

    Nota  

    Per le app di Windows Phone Store, i trasferimenti in background continuano anche quando l'app non è in primo piano. Poiché l'app non è in esecuzione in questo scenario, non riceverà una notifica al termine del trasferimento. Quando riprendi l'app, se controlli lo stato di un trasferimento completato noterai che è BackgroundTransferStatus.Running. In ogni caso, se associ il trasferimento come nel codice di esempio precedente, il gestore di completamento dell'attività verrà attivato e lo stato del trasferimento verrà aggiornato.

Timeout della richiesta

Ci sono due principali scenari di timeout della connessione da prendere in considerazione.

  • Quando si stabilisce una nuova connessione per un trasferimento, se la richiesta di connessione non viene stabilita entro cinque minuti viene interrotta.

  • Dopo che la connessione è stata stabilita, verrà interrotto qualsiasi messaggio di richiesta HTTP che non abbia ricevuto risposta entro due minuti.

In entrambi gli scenari, e posto che la connettività Internet esista, la funzionalità Trasferimento in background effettuerà altri tre tentativi di inviare la richiesta. Se non viene rilevata connettività Internet, eventuali ulteriori richieste attenderanno che venga rilevata.

Per operazioni XHR, è possibile definire specifici valori di timeout mediante la proprietà WinJS.Promise.timeout. Per altre informazioni su come eseguire questa operazione, vedi Impostazione dei valori di timeout quando si usa WinJS.xhr.

Linee guida per il debug

L'interruzione di una sessione di debug in Microsoft Visual Studio è paragonabile alla chiusura della tua app. Anche durante il debug, la tua app dovrebbe enumerare e quindi riprendere, riavviare o annullare eventuali download esistenti dalla sessione precedente. Ad esempio, puoi impostare l'app in modo che annulli le operazioni di download persistenti enumerate all'avvio dell'app se le operazioni precedenti non sono di alcun interesse per la sessione di debug corrente.

In presenza di aggiornamenti del progetto di Visual Studio, come modifiche del manifesto dell'app, e se l'app viene disinstallata e ridistribuita, GetCurrentUploadsAsync non può enumerare le operazioni create con la distribuzione dell'app precedente.

Per altre informazioni, vedi Debug e test delle app di Windows Store.

Se usi Trasferimento in background durante lo sviluppo, è possibile che le cache interne delle operazioni di trasferimento attive e completate perdano la sincronizzazione. Ciò può impedire l'avvio di nuove operazioni di trasferimento o l'interazione con le operazioni esistenti e gli oggetti BackgroundTransferGroup. In alcuni casi il tentativo di interagire con le operazioni esistenti può generare un arresto anomalo. Questo esito può verificarsi se la proprietà TransferBehavior è impostata su Parallel. Questo problema si verifica solo in alcuni scenari durante lo sviluppo e non è applicabile agli utenti finali dell'app.

Quattro scenari di Visual Studio possono causare questo problema.

  • Crei un nuovo progetto con lo stesso nome di app di un progetto esistente ma in un linguaggio diverso (ad esempio, da C++ a C#).
  • Modifichi l'architettura di destinazione (ad esempio, da x86 a x64) in un progetto esistente.
  • Modifichi la lingua (ad esempio, da una lingua non associata ad alcun paese a en-US) in un progetto esistente.
  • Aggiungi o rimuovi una funzionalità nel manifesto del pacchetto (ad esempio, aggiungendo Autenticazione Enterprise) in un progetto esistente.

Le normali operazioni di manutenzione dell'app, inclusi gli aggiornamenti del manifesto che aggiungono o rimuovono funzionalità, non attivano questo problema nelle distribuzioni dell'app per l'utente finale.

Per evitare il problema, disinstalla completamente tutte le versioni dell'app e ridistribuiscila con il nuovo linguaggio, la nuova architettura, la nuova lingua o la nuova funzionalità. L'operazione può essere eseguita tramite la schermata Start o con PowerShell e il cmdlet Remove-AppxPackage.

Riepilogo e passaggi successivi

In questo argomento abbiamo analizzato come scaricare file tramite le API Background Transfer in JavaScript. Abbiamo inoltre analizzato le differenze tra le due e sottolineato come l'applicazione pratica dipenda dalle dimensioni e dalla durata di un download di file.

Puoi anche usare XHR e Trasferimento in background per il caricamento di file. Per una spiegazione dei concetti di base ed esempi, vedi Come caricare un file.

Argomenti correlati

Altro

Programmazione asincrona in JavaScript con le promesse

Creare la prima app di Windows Runtime in JavaScript

Come configurare le funzionalità di rete

Come scaricare un file con WinJS xhr

Come caricare un file

Riferimenti

HttpClient

Windows.Networking.BackgroundTransfer

WinJS.XHR

Esempi

Esempio di trasferimento in background

Esempio di HttpClient