So wird’s gemacht: Herunterladen einer Datei (HTML)
[ Dieser Artikel richtet sich an Windows 8.x- und Windows Phone 8.x-Entwickler, die Windows-Runtime-Apps schreiben. Wenn Sie für Windows 10 entwickeln, finden Sie weitere Informationen unter neueste Dokumentation]
In diesem Abschnitt wird erläutert, wie Sie eine Datei herunterladen.
Apps können mithilfe der in diesem Thema behandelten APIs mit Webdiensten interagieren, um gängige Medienformate wie Fotos, Musik und Video zu verwenden oder zu teilen.
Wenn Sie eine App in JavaScript entwickeln, stehen Ihnen zwei primäre Optionen zum Anfordern von Dateien aus dem Internet zur Verfügung. Kleine Dateien (z. B. häufig abgerufene Websiteobjekte) können mit XHR heruntergeladen werden, um die asynchrone HTTP-GET-Anforderung auszuführen. Diese Funktion umschließt einen XMLHttpRequest-Aufruf in einer Zusage, dem Programmiermuster, das asynchrones Verhalten in JavaScript ermöglicht.
Alternativ kann die App Background Transfer verwenden, um bei Übertragungen größerer Medien (Video und Musik), während derer vielleicht die App mehrmals angehalten wird und/oder das Netzwerk nicht immer verfügbar ist, Einheitlichkeit zu gewährleisten. Allgemeine Informationen zu Hintergrundübertragungen finden Sie unter Übertragen von Daten im Hintergrund.
Voraussetzungen
Allgemeine Informationen zum Erstellen einer JavaScript-App finden Sie unter Erstellen Ihrer ersten Windows Store-App mit JavaScript. Darüber hinaus werden in diesem Thema JavaScript-Zusagen zum Ausführen asynchroner Vorgänge verwendet. Weitere Informationen zu diesem Programmierungsmuster finden Sie unter Asynchrone Programmierung in JavaScript mit Zusagen.
Damit Ihre App im Netzwerk verwendet werden kann, müssen Sie die entsprechende Funktion in der Projektdatei Package.appxmanifest festlegen. Definitionen der einzelnen Netzwerkfunktionen finden Sie unter So wird's gemacht: Konfigurieren von Netzwerkisolationsfunktionen.
Alle Beispiele für die Hintergrundübertragung in diesem Thema basieren auf dem Beispiel für eine Hintergrundübertragung.
Herunterladen einer Datei mithilfe von XHR
Rufen Sie zum Initiieren einer grundlegenden asynchronen HTTP-Anforderung mit JavaScript XHR auf, und stellen Sie relevante Anforderungsdaten mithilfe des Option-Parameters bereit. Dieser Methodenaufruf ist standardmäßig eine GET-Anforderung. Daher sind die einzigen erforderlichen Werte, die über Option bereitgestellt werden, die URL und der "responseType". Bei vielen Webdiensten ist jedoch eine Authentifizierung erforderlich. Diese Anmeldeinformationen sollten beim Aufrufen von XHR zum Anfordern von Ressourcen von einem sicheren Webdienst aufgenommen werden.
Bei einem XHR GET-Vorgang muss außerdem der in der Antwort erwartete Inhaltstyp mit dem "responseType" im Option-Parameter angegeben werden. In unserem Beispiel wurde eine PNG-Datei angefordert. Der responseType-Wert ist daher "blob". Eine vollständige Liste der unterstützten Inhaltstypen und Beispiele zum Anfordern dieser Typen finden Sie unter So wird's gemacht: Herunterladen einer Datei mit "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 verfügt jede Zusage über zwei Funktionen, mit denen Sie das Ergebnis eines asynchronen Vorgangs behandeln können: "then" und "done". Beide Funktionen akzeptieren drei Parameter: Eine Funktion, die aufgerufen wird, wenn der Download abgeschlossen ist (d. h. wenn readyState gleich 4 ist), eine Funktion, die aufgerufen wird, wenn ein Fehler vorliegt, und eine Funktion, die aufgerufen wird, während der Download ausgeführt wird (d. h. wenn readyState gleich 2 oder 3 ist). Nur die done-Funktion löst eine Ausnahme aus, wenn ein Fehler nicht behandelt wird. Diese Funktion wird bevorzugt, wenn keine Fehlerfunktion angegeben wird.
Herunterladen einer Datei mithilfe der Hintergrundübertragung
Bei der Hintergrundübertragung erfolgt jeder Download als DownloadOperation. Dabei werden eine Reihe von Steuerungsmethoden zum Anhalten, Fortsetzen, Neustarten und Abbrechen des Vorgangs verfügbar gemacht. App-Ereignisse (z. B. Anhalten oder Beenden) und Konnektivitätsänderungen werden vom System automatisch durch DownloadOperation behandelt. Downloads werden bei Anhalten oder Unterbrechen der App und auch nach dem Beenden der App fortgesetzt. In Szenarien für mobile Netzwerke wird außerdem durch Festlegen der CostPolicy-Eigenschaft angegeben, ob die App Downloads startet oder fortsetzt, wenn für die Internetkonnektivität ein getaktetes Netzwerk verwendet wird.
In den folgenden Beispielen werden die Erstellung und Initialisierung eines einfachen Downloads sowie das Aufzählen und Fortsetzen von in einer vorherigen App-Sitzung gespeicherten Vorgängen erläutert.
Konfigurieren und Starten eines Dateidownloads mit Hintergrundübertragung
Das folgende Beispiel veranschaulicht, wie mit Zeichenfolgen, die einen URI und einen Dateinamen darstellen, ein Uri-Objekt und die StorageFile erstellt werden können, die die angeforderte Datei enthalten. Im Beispiel wird die neue Datei automatisch an einem vordefinierten Speicherort abgelegt. Alternativ kann Benutzern mithilfe von FileSavePicker ermöglicht werden, den Speicherort der Datei auf dem Gerät anzugeben. Die load-Methode, die zum Neuzuweisen der Rückrufe von DownloadOperation aufgerufen wird, wenn der Vorgang nach Beendigung der App fortgesetzt wird, befindet sich in der "DownloadOp"-Klasse, die weiter unten in diesem Abschnitt definiert wird.
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); } }; }
Beachten Sie die asynchronen Methodenaufrufe, die mit JavaScript-Zusagen definiert sind. Aus Zeile 17 des vorherigen Codebeispiels geht Folgendes hervor:
promise = download.startAsync().then(complete, error, progress);
Nach dem Async-Methodenaufruf folgt eine then-Anweisung, die von der App definierte Methoden angibt, die aufgerufen werden, wenn ein Ergebnis aus dem Async-Methodenaufruf zurückgegeben wird. Weitere Informationen zu diesem Programmierungsmuster finden Sie unter Asynchrone Programmierung in JavaScript mit Zusagen.
Hinzufügen weiterer Methoden zur Vorgangssteuerung
Der Grad der Steuerung lässt sich durch Implementieren zusätzlicher DownloadOperation-Methoden erhöhen. Wenn Sie beispielsweise dem obigen Beispiel den folgenden Code hinzufügen, wird das Abbrechen des Downloads ermöglicht.
// 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); } };
Bei Abschluss oder Abbruch von DownloadOperation werden alle zugeordneten Systemressourcen freigegeben. Wenn die App allerdings vor Auftreten eines dieser Ereignisse beendet wird, werden die Downloads angehalten und im Hintergrund beibehalten. In den folgenden Beispielen wird gezeigt, wie Sie beibehaltene Downloads in einer neuen App-Sitzung fortsetzen.
Aufzählen beibehaltener Vorgänge beim Start
Bevor Sie die Funktion zum Aufzählen beibehaltener Vorgänge definieren, müssen Sie ein Array erstellen, das die zurückzugebenden DownloadOperation-Objekte enthält:
var downloadOps = [];
Im nächsten Schritt definieren Sie die Funktion, die alle beibehaltenen Vorgänge aufzählt und im Array speichert. Die load-Methode, die zum Neuzuweisen von Rückrufen für eine beibehaltene DownloadOperation aufgerufen wird, befindet sich im Beispiel für die DownloadOp-Klasse, die weiter unten in diesem Abschnitt definiert wird.
// 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); } });
Hinweis
Für Windows Phone Store-Apps werden Hintergrundübertragungen fortgesetzt, während Ihre App nicht im Vordergrund ausgeführt wird. Da Ihre App in einem solchen Szenario nicht ausgeführt wird, erhält sie keine Benachrichtigung, wenn die Übertragung abgeschlossen ist. Wenn Ihre App fortgesetzt wird und Sie nur den Status einer abgeschlossenen Übertragung überprüfen, wird BackgroundTransferStatus.Running als Status zurückgegeben. Fügen Sie aber wie im obigen Beispiel einen Handler an die Übertragung an, wird der Aufgabenabschlusshandler ausgelöst, und der Übertragungsstatus wird aktualisiert.
Zeitüberschreitungen bei Anforderungen
Es müssen zwei primäre Szenarien zu Verbindungszeitüberschreitungen berücksichtigt werden:
Beim Herstellen einer neuen Verbindung für die Übertragung wird die Verbindungsanforderung abgebrochen, wenn die Verbindung nicht innerhalb von fünf Minuten hergestellt wird.
Nach dem Herstellen einer Verbindung wird eine HTTP-Anforderungsnachricht abgebrochen, auf die nicht innerhalb von zwei Minuten reagiert wurde.
In der Annahme, dass Internetkonnektivität besteht, wiederholt die Hintergrundübertragung in beiden Szenarien eine Anforderung automatisch bis zu drei Mal. Wenn keine Internetkonnektivität erkannt wird, warten zusätzliche Anforderungen, bis Konnektivität vorhanden ist.
Für XHR-Vorgänge können mit der WinJS.Promise.timeout-Eigenschaft bestimmte Timeoutwerte definiert werden. Weitere Informationen hierzu finden Sie unter Festlegen von Timeoutwerten bei der Verwendung von "WinJS.xhr".
Debugging-Leitfaden
Das Beenden einer Debugsitzung in Microsoft Visual Studio ist mit dem Schließen der App vergleichbar. Auch beim Debuggen sollte die App alle von der vorhergehenden Sitzung beibehaltenen Downloads auflisten und dann fortsetzen, neu starten oder abbrechen. Sie können beispielsweise aufgelistete beibehaltene Downloadvorgänge beim App-Start durch die App abbrechen lassen, wenn kein Interesse an vorherigen Operationen für die aktuelle Debugsitzung besteht.
GetCurrentUploadsAsync kann Vorgänge nicht auflisten, die mithilfe der vorherigen App-Bereitstellung erstellt werden, wenn Visual Studio-Projektupdates, wie Änderungen am App-Manifest, vorhanden sind und die App deinstalliert und erneut bereitgestellt wird.
Weitere Informationen finden Sie unter Debuggen und Testen von Windows Store-Apps.
Bei der Verwendung von Hintergrundübertragungen während der Entwicklung kann es vorkommen, dass die internen Caches aktiver und abgeschlossener Übertragungsvorgänge nicht mehr synchron sind. Dies kann zur Folge haben, dass keine neuen Übertragungsvorgänge gestartet werden können, oder dass keine Interaktion mit vorhandenen Vorgängen und BackgroundTransferGroup-Objekten mehr möglich ist. In einigen Fällen wird durch den Versuch einer Interaktion mit vorhandenen Vorgängen ein Absturz ausgelöst. Dies kann vorkommen, wenn die TransferBehavior-Eigenschaft auf Parallel festgelegt ist. Dieses Problem tritt nur bei bestimmten Szenarien während der Entwicklung auf und betrifft nicht die Endbenutzer Ihrer App.
Vier Szenarien mit Visual Studio können dieses Problem auslösen.
- Sie erstellen ein neues Projekt mit demselben App-Namen wie ein vorhandenes Projekt, jedoch einer anderen Sprache (z. B. C# statt C++).
- Sie ändern die Zielarchitektur (z. B. von x86 zu x64) in einem vorhandenen Projekt.
- Sie ändern die Kultur (z. B. von neutral zu en-US) in einem vorhandenen Projekt.
- Sie fügen in einem vorhandenen Projekt eine Funktion im Paketmanifest (z. B. Unternehmensauthentifizierung) hinzu oder entfernen eine.
Normale App-Wartungen wie z. B. Manifestaktualisierungen, bei denen Funktionen hinzugefügt oder entfernt werden, lösen dieses Problem in den Bereitstellungen Ihrer App für Endbenutzer nicht aus.
Umgehen Sie dieses Problem, indem Sie alle Versionen der App vollständig deinstallieren und sie mit der neuen Sprache, Architektur, Kultur oder Funktion erneut bereitstellen. Dies ist auf der Startseite oder mithilfe von PowerShell und dem Remove-AppxPackage-Cmdlet möglich.
Zusammenfassung und nächste Schritte
Sie haben in diesem Thema erfahren, wie Dateien mit den Background Transfer-APIs in JavaScript heruntergeladen werden. Wir haben die Unterschiede zwischen den beiden APIs erläutert und veranschaulicht, wie praktische Anwendungen von der Größe und Dauer eines Dateidownloads abhängen.
Sie können XHR und die Hintergrundübertragung auch zum Hochladen von Dateien verwenden. Eine Erläuterung der wichtigsten Konzepte und Beispiele finden Sie unter So wird's gemacht: Hochladen einer Datei.
Verwandte Themen
Weitere Themen
Asynchrone Programmierung in JavaScript mit Zusagen
Erstellen Ihrer ersten Windows-Runtime-App mit JavaScript
So wird's gemacht: Konfigurieren von Netzwerkfunktionen
So wird's gemacht: Herunterladen einer Datei mit "WinJS.xhr"
So wird's gemacht: Hochladen einer Datei
Referenz
Windows.Networking.BackgroundTransfer
Beispiele