Quickstart: Downloading a file (Windows Store apps using JavaScript and HTML)

Language: JavaScript and HTML | VB/C#/C++ and XAML
0 out of 6 rated this helpful - Rate this topic

This topic will show you how to download a file.

Windows Store apps can use the APIs discussed in this topic to enable their app to interact with web services to consume or share popular media formats like photos, music, and video.

When developing a Windows Store app in JavaScript there are two primary options for requesting files from locations on the Internet. Small files, like site assets that are retrieved frequently, can be downloaded using XHR to make the asynchronous HTTP GET request. This function wraps an XMLHttpRequest call in a promise, the programming pattern that enables asynchronous behavior in JavaScript.

Alternatively, to provide a consistent experience when downloading larger media (video and music) with an operational lifetime that may span beyond multiple app suspensions and/or changes in network availability, your Windows Store app can use Background Transfer. For a high-level look at Background Transfer, see Transferring data in the background.

Prerequisites

For general help creating a JavaScript Windows Store app, see Create your first Windows Store app using JavaScript. Additionally, JavaScript promises are used in this topic to complete asynchronous operations. For more information on this programming pattern, see Asynchronous programming in JavaScript using promises.

To ensure your Windows Store app is network ready, you must set the capability in the project Package.appxmanifest file. For a definition of each network capability, see How to configure network isolation capabilities.

All Background Transfer examples in this topic are based on the Background Transfer sample.

Downloading a file using XHR

To initiate a basic asynchronous HTTP request using JavaScript, call XHR and supply it with relevant request data using the Option parameter. By default this method call is a GET request, so the only required values supplied via Option are the URL and responseType. However, many web services require authentication, and these credentials should be included when calling XHR to request resources from any secure web service.

An XHR GET operation also requires that the type of content expected in the response is specified using responseType in the Option parameter. In our example we requested a .png file, so our responseType value is "blob". For a complete list of supported content types and examples of how to request them, see Quickstart: Connecting to a web service using WinJS.xhr.



WinJS.xhr({ url: "http://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, every promise has two functions that you can use to handle the results of an asynchronous operation: then and done. Both functions take three parameters: a function that's called when the download is complete (that is, when readyState is 4), a function that's called when there's an error, and a function that's called while the download is in progress (when readyState is 2 or 3). Only the done function throws an exception if an error is not handled. This function is preferred when an error function isn't provided.

Downloading a file using Background Transfer

When using Background Transfer, each download exists as a DownloadOperation that exposes a number of control methods used to pause, resume, restart, and cancel the operation. App events (e.g. suspension or termination) and connectivity changes are handled automatically by the system per DownloadOperation; downloads will continue during app suspension periods or pause and persist beyond app termination. For mobile network scenarios, setting the CostPolicy property will indicate whether or not your app will begin or continue downloads while a metered network is being used for Internet connectivity.

The following examples will walk you through the creation and initialization of a basic download, and how to enumerate and reintroduce operations persisted from a previous app session.

Hh700370.wedge(en-us,WIN.10).gifConfigure and start a Background Transfer file download

  • The following example demonstrates how strings representing a URI and a file name can be used to create a Uri object and the StorageFile that will contain the requested file. In this example, the new file is automatically placed in a pre-defined location. Alternatively, FileSavePicker can be used allow users to indicate where to save the file on the device. Note that the load method called to re-assign callbacks to the DownloadOperation, should it persist through app termination, is in the DownloadOp class defined later in this section.

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

    Note the asynchronous method calls defined using JavaScript promises. Looking at line 17 from the previous code example:

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

    The async method call is followed by a then statement which indicates methods, defined by the app, that are called when a result from the async method call is returned. For more information on this programming pattern, see Asynchronous programming in JavaScript using promises.

Hh700370.wedge(en-us,WIN.10).gifAdding additional operation control methods

  • The level of control can be increased by implementing additional DownloadOperation methods. For example, adding the following code to the example above will introduce the ability to cancel the 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);
        }
    };
    
    
    

On completion or cancellation of a DownloadOperation, any associated system resources are released. However, if your app is terminated before either of these events occur, downloads will pause and persist in the background. The following examples demonstrate how to re-introduce persisted downloads into a new app session.

Hh700370.wedge(en-us,WIN.10).gifEnumerate persisted operations at start-up

  1. Before defining the function that enumerates persisted operations, we need to create an array that will contain the DownloadOperation objects that it will return:

    
    var downloadOps = [];
    
    
    
  2. Next we define the function that enumerates persisted operations and stores them in our array. Note that the load method called to re-assign callbacks for a persisted DownloadOperation is in the DownloadOp example we define later in this section.

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

Request Timeouts

There are two primary connection timeout scenarios to take into consideration:

  • When establishing a new connection for a transfer, the connection request is aborted if it is not established within five minutes.

  • After a connection has been established, an HTTP request message that has not received a response within two minutes is aborted.

In either scenario, assuming there is Internet connectivity, Background Transfer will automatically retry a request up to three times. In the event Internet connectivity is not detected, additional requests will wait until it is.

For XHR operations, specific timeout values can be defined using the WinJS.Promise.timeout property. For more information on how this is accomplished, see Setting time-out values when using WinJS.xhr.

Summary and next steps

In this topic we reviewed how to download files using the and Background Transfer APIs in JavaScript. We reviewed the differences between the two and highlighted how practical application depends on the size and lifetime of a file download.

You can also use XHR and Background Transfer to upload files. For an explanation of core concepts and examples, see Quickstart: Uploading a file.

Related topics

Quickstart: Connecting to a web service using WinJS.xhr
Quickstart: Uploading a file
WinJS.XHR
Windows.Networking.BackgroundTransfer
Background Transfer sample

 

 

Build date: 11/29/2012

Did you find this helpful?
(1500 characters remaining)
© 2013 Microsoft. All rights reserved.