How to download a file with WinJS.xhr (HTML)

[ This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation ]

WinJS.xhr provides an easy way to download web content in your app. This topic shows how to download a file using WinJS.xhr, handle any errors, and report on the progress of the download. It also shows how to download different types of content.

The WinJS.xhr function returns a WinJS.Promise. For more information about asynchronous methods in general and JavaScript promises in particular, see Asynchronous programming in JavaScript.

Warning  It is now possible to use XMLHttpRequest to transfer extremely large objects, such as Blob objects and FormData objects, which might take a long time to complete. Because apps can be terminated at any time, you should consider using the file upload APIs in the Windows Runtime API for these operations. For more info about uploading content, see How to upload a file.

 

Prerequisites

To complete this procedure, you need to be able to create a basic app that uses the Windows Library for JavaScript template. For help creating your first app, see Create your first Windows Runtime app using JavaScript.

Set up your app for accessing the web

Apps need to add certain capabilities explicitly, such as accessing the network. For more information about capabilities, see App capability declarations and How to configure network capabilities.

  1. In Visual Studio, create a blank JavaScript app.

  2. Open the package.appxmanifest file and go to the Capabilities tab.

  3. For the Windows version of the sample, the Internet (Client) capability should already be selected, but if not select it now. If the app might need to connect as a client to web services on a home network or work network, then the Private Networks (Client & Server) capability is also needed.

    For the Windows Phone version of the sample, select the Internet (Client & Server) capability.

    Note  On Windows Phone, there is only one network capability (Internet (Client & Server) which enables all network access for the app.

     

Basic downloading

In this step you download a Web page and report when the downoad is completed.

  1. Create a blank app and name it XhrExample.

  2. In the body of the HTML in the default.html file, add a DIV element to contain the completed notification, progress, and error reports.

    <div id="xhrReport"></div>
    
  3. Also in the body of the HTML in the default.html file, add a SCRIPT element that contains the WinJS.xhr code.

    var xhrDiv = document.getElementById("xhrReport");
    xhrDiv.style.color = "#000000";
    
    WinJS.xhr({ url: "https://www.microsoft.com" })
        .done(function complete(result) {
            // Report download.
            xhrDiv.innerText = "Downloaded the page";
            xhrDiv.style.backgroundColor = "#00FF00";
    });
    

    In the preceding code, the complete function writes to the DIV element that the download is complete.

    Notice the syntax of WinJS.xhr. This function takes a single parameter in which you specify the options. The only required option is url. You can read about other options in the reference documentation.

    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 is called when the download is complete (that is, when readyState is 4), a function that's called when there is an error, and a function that is called while the download is in progress (when readyState is 2 or 3). Only the done function throws an exception if an error isn't handled. You should use the done function when you don't want to provide an error function.

  4. Build and run the app in debug mode. You should see a green box that contains the words "Downloaded the page."

  5. Now try provoking an error so that you can see what happens. Replace the URL https://www.microsoft.com in the code with http://www.nosuchsite.example. When you run the app in debug mode, you should be taken to the debugger statement in the terminateAppHandler function in the WinJS file base.js.

Handling errors

In this step you add an error handler that writes to the DIV when an error occurs.

  • Add an error handler to the code you added in step 3 above. With WinJS.xhr, the error function has a parameter that represents the request.

    var xhrDiv = document.getElementById("xhrReport");
    
    WinJS.xhr({ url: "http://www.nosuchsite.example" })
        .done(function complete(result) {
            // Report download.
            xhrDiv.innerText = "Downloaded the page";
            xhrDiv.style.backgroundColor = "#00FF00"; 
            },
            function error(result){
                xhrDiv.innerHTML = "Got error: " + result.statusText;
                xhrDiv.style.backgroundColor = "#FF0000";
         });
    

    When you run the app, you should see a red box that reports the error.

Reporting progress

In this step, you report on the progress of the download by providing a progress function to the done function.

  • Add a progress handler to the code you added in the previous step. With WinJS.xhr, the progress function has a parameter that represents the request.

    var xhrDiv = document.getElementById("xhrReport");
    
    WinJS.xhr({ url: "https://www.microsoft.com" })
        .done(function complete(result) {
            // Report download.
                xhrDiv.innerText = "Downloaded the page";
                xhrDiv.style.backgroundColor = "#00FF00"; 
            },
            function error(error){
                xhrDiv.innerHTML = "Got error: " + error.statusText;
                xhrDiv.style.backgroundColor = "#FF0000";
            }, 
            function progress(result) {
                xhrDiv.innerText = "Ready state is " + result.readyState;
                xhrDiv.style.backgroundColor = "#0000FF";
        });
    

    When you run the code, you should see a blue box that contains the words "Ready state is 2" or "Ready state is 3" before you see a green box that contains the words "Downloaded the page." (To see the blue box, you might have to slow things down by setting a breakpoint inside the progress function.)

Downloading different types of content

You can download different types of content by using WinJS.xhr. You indicate the content type in the responseType option of WinJS.xhr.

The following types are supported:

  • arraybuffer: The type of response is an ArrayBuffer. This type is used to represent binary content as an array of type Int8 or Int64, or of another integer or float type. (See Typed Arrays for more information about the different typed arrays currently supported in JavaScript.) The responseText and responseXML properties are undefined.

    This code shows how to handle an arraybuffer response:

    
    <div id="xhrDiv"></div>
    <script type="text/javascript">
        WinJS.xhr({ url: "https://www.microsoft.com", responseType: "arraybuffer" })
            .done(function complete(result) {
                var arrayResponse = result.response;
                var ints = new Uint32Array(arrayResponse.byteLength / 4);
    
                xhrDiv.style.backgroundColor = "#00FF00";
                xhrDiv.innerText = "Array is " + ints.length + "uints long";
            });
    </script> 
    
  • blob: The type of response is a Blob. This is used to represent binary content as a single binary entity. The responseText and responseXML properties are undefined.

    This code shows how to handle a blob:

    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;
            });
    
  • document: The type of response is an XML Document Object Model (XML DOM) object. This is used to represent XML content, that is, content that has a MIME type of "text/xml". If the MIME type is anything other than "text/xml", the responseXML is of the same type, and responseText is undefined.

  • json: The type of response is String. This is used to represent JSON strings. responseText is also of type String, and responseXML is undefined.

  • ms-stream: The type of response is msStream, and responseText and responseXML are undefined. This response type is not defined in the W3C specification, but it is supported to make it easier to handle streaming data. For more information, see XMLHttpRequest enhancements.

  • text (the default): The type of response and responseText is String.

    This example shows how to handle a text response:

    WinJS.xhr({ url: "https://www.msdn.microsoft.com/library", responseType: "text" 
        .done(
            function (request) {
                var text = request.responseText;
                var subText = text.substring(text.indexOf("Welcome"), text.indexOf("services.") + 9);
                xhrDiv.innerHTML = subText;
        });
    

Summary

You can find more information about WinJS.xhr and XMLHttpRequest in the following topics:

Other resources

App capability declarations

Connecting to web services

How to configure network capabilities

How to create a mashup using WinJS.xhr

How to upload binary data with WinJS.xhr

Setting timeout values with WinJS.xhr or HttpClient

Reference

WinJS.xhr

XMLHttpRequest

XMLHttpRequest enhancements

Samples

Integrating content and controls from web services sample

Web authentication sample