How to upload binary data 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 ]

You can upload and download binary data when you use WinJS.xhr (which wraps XMLHttpRequest). This example shows how to upload a bitmap from your Pictures. The Windows Runtime method that is used to open the bitmap file returns an IRandomAccessStream, so you must use MSApp.createBlobFromRandomAccessStream to convert it to a Blob.

Warning  You can now use XMLHttpRequest to upload or download objects that are larger than a few MB, such as Blob objects and FormData objects, which may take a long time to complete. Because apps can be terminated at any time, you should consider using the Windows Runtime background transfer APIs for these operations. For more information about uploading and downloading content, see How to upload a file and How to download a file. For a general discussion of background transfer, see Transferring data in the background.

 

Prerequisites

We assume that you can create a basic app that uses Windows Library for JavaScript. For help creating your first app, see Create your first Windows Runtime app using JavaScript.

Instructions

Step 1: Set up your app for accessing Pictures and the web

Apps need to add certain capabilities explicitly, such as accessing a particular library on your hard drive, or 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.

     

  4. Select the Pictures Library capability.

Step 2: Upload the bitmap

There are a number of asynchronous methods that handle file access. These asynchronous methods are treated like any other promise in JavaScript.

Note  For more information, see Asynchronous programming in JavaScript.

 

  1. In the BODY section of the default.html file, add a DIV element that reports on the success or failure of the upload, and give it an ID of "picDiv":

    <div id="picDiv"></div>
    
  2. In the code, set up references to the DIV and to Pictures:

    var picDiv = document.getElementById("picDiv");
    var picturesLibrary = Windows.Storage.KnownFolders.picturesLibrary;
    
  3. Find the file you want in Pictures. You could just upload this file by using WinJS.xhr, but let's say that you want to re-encode the file or do some other processing on it. In the completeFile function in the getFileAsync method's then clause, open the file by using openAsync. Then, in the completeStream function in the openAsync method's then clause, do whatever processing you need to do on the open file stream, which is of type IRandomAccessStream.

    picturesLibrary.getFileAsync("myBitmap.bmp").then(
        function completeFile(file) {
            return file.openAsync(Windows.Storage.FileAccessMode.readWrite);
            }).then(
                function completeStream(stream) {
                    // Do processing. 
        });
    
  4. Now for the upload. WinJS.xhr (and XMLHttpRequest) don't accept uploads of type IRandomAccessStream, so you need to convert the stream to a Blob. There's a helper function MSApp.createBlobFromRandomAccessStream that does just that. You can add the resulting Blob to the data option of WinJS.xhr. You can handle the success or failure of the upload in the then clause of WinJS.xhr .

    picturesLibrary.getFileAsync("myBitmap.bmp").then(
        function completeFile(file) {
            return file.openAsync(Windows.Storage.FileAccessMode.readWrite);
        }).then(
            function completeStream(stream) {
                // Do processing. 
                var blob = MSApp.createBlobFromRandomAccessStream("image/bmp", stream);
                return WinJS.xhr({ type: "POST", url: <URI of the website>, data: blob });
            }).then(
                function (request) {
                    picDiv.textContent = "uploaded file";
                }, 
                function (error) {
                    picDiv.textContent = "error uploading file";
        });
    
  5. Run the app. You should be able to upload the file.

Other resources

App capability declarations

Connecting to web services

How to configure network capabilities

How to download a file 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