Title: Can open blob returned by XMLHTTPRequest, but can't upload to Azure
Tags: javascript;node.js;azure;azure-storage;azure-blob-storage
Question: I am able to upload a file to my vendors API, and the vendor responds with a .png file as binary data. I am able to write this out to a blob in the browser, but I can't get it to upload in Azure blob storage. I also tried uploading it to a Web directory using fs.writefile but that produces a corrupt/non-bitmap image. 

Ideally, I would like to upload my blob directly into Azure, but when I try it gives me the following error:

```
  TypeError: must start with number, buffer, array or string
```

If I need to upload the blob to a Web directory and use Azure's createBlockBlobFromLocalFile, I would be more than happy to, but my attempts have failed thus far. 

Here is my XMLHTTPRequest that opens the image in the browser that is returned after I post my file:

var form = document.forms.namedItem("fileinfo");
form.addEventListener('submit', function (ev) {

var oData = new FormData(form);

```var xhr = new XMLHttpRequest();
xhr.responseType = "arraybuffer";

xhr.open("POST", "http://myvendorsapi/Upload", true);
xhr.onload = function (oEvent) {
    if (xhr.status == 200) {
        var blob = new Blob([xhr.response], { type: "image/png" });
        var objectUrl = URL.createObjectURL(blob);
        window.open(objectUrl);

        console.log(blob);
        var containerName = boxContainerName;
        var filename = 'Texture_0.png';

        $http.post('/postAdvanced', { containerName: containerName, filename: filename, file: blob }).success(function (data) {
            //console.log(data);
            console.log("success!");
        }, function (err) {
            //console.log(err);
        });

    } else {
        oOutput.innerHTML = "Error " + xhr.status + " occurred when trying to upload your file.<br \/&gt;";
    }
};

xhr.send(oData);
ev.preventDefault();
}, false);
```

Here is my Node backend for the /postAdvanced call:

```app.post('/postAdvanced', function (req, res, next) {
    var containerName = req.body.containerName;
    var filename = req.body.filename;
    var file = req.body.file;
    if (!Buffer.isBuffer(file)) {
    // Convert 'file' to a binary buffer
    }

    var options = { contentType: 'image/png' };
    blobSvc.createBlockBlobFromText(containerName, filename, file, function (error, result, response) {
        if (!error) {
            res.send(result);
        } else {
            console.log(error);
        }
    });
})
```

If someone can't help me with uploading directly to Azure, if I can get how to upload this blob to a directory, I can get it into Azure via createBlockBlobFromLocalFile

Comment: When I console.log the file variable it is an empty object. Could it be that I am not passing anything back to node/what can be done?

Here is the accepted answer: I have solved the issue. I needed to base64 encode the data on the client side before passing it to node to decode to a file. I needed to use XMLHTTPRequest to get binary data properly, as jQuery AJAX appears to have an issue with returning (see here: http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/). 

Here is my front end:

```var form = document.forms.namedItem("fileinfo");
form.addEventListener('submit', function (ev) {

 var oData = new FormData(form);

    var xhr = new XMLHttpRequest();
    xhr.responseType = "arraybuffer";

    xhr.open("POST", "http://vendorapi.net/Upload", true);
    xhr.onload = function (oEvent) {
        if (xhr.status == 200) {
            var blob = new Blob([xhr.response], { type: "image/png" });
            //var objectUrl = URL.createObjectURL(blob);
            //window.open(objectUrl);
            console.log(blob);
            var blobToBase64 = function(blob, cb) {
                var reader = new FileReader();
                reader.onload = function() {
                    var dataUrl = reader.result;
                    var base64 = dataUrl.split(',')[1];
                    cb(base64);
                };
                reader.readAsDataURL(blob);
            };

            blobToBase64(blob, function(base64){ // encode
                var update = {'blob': base64};
                var containerName = boxContainerName;
                var filename = 'Texture_0.png';

                $http.post('/postAdvancedTest', { containerName: containerName, filename: filename, file: base64}).success(function (data) {
                    //console.log(data);
                    console.log("success!");

                    // Clear previous 3D render
                    $('#webGL-container').empty();

                    // Generated new 3D render
                    $scope.generate3D();
                }, function (err) {
                    //console.log(err);
                });
            })
        } else {
            oOutput.innerHTML = "Error " + xhr.status + " occurred when trying to upload your file.<br \/&gt;";
        }
    };

    xhr.send(oData);
    ev.preventDefault();
}, false);
```

Node Backend:

```app.post('/postAdvancedTest', function (req, res) {
    var containerName = req.body.containerName
    var filename = req.body.filename;
    var file = req.body.file;
    var buf = new Buffer(file, 'base64'); // decode

    var tmpBasePath = 'upload/'; //this folder is to save files download from vendor URL, and should be created in the root directory previously.
    var tmpFolder = tmpBasePath + containerName + '/';

    // Create unique temp directory to store files
    mkdirp(tmpFolder, function (err) {
        if (err) console.error(err)
        else console.log('Directory Created')
    });

    // This is the location of download files, e.g. 'upload/Texture_0.png'
    var tmpFileSavedLocation = tmpFolder + filename;

    fs.writeFile(tmpFileSavedLocation, buf, function (err) {
        if (err) {
            console.log("err", err);
        } else {
            //return res.json({ 'status': 'success' });
            blobSvc.createBlockBlobFromLocalFile(containerName, filename, tmpFileSavedLocation, function (error, result, response) {
                if (!error) {
                    console.log("Uploaded" + result);

                    res.send(containerName);
                }
                else {
                    console.log(error);
                }
            });
        }
    }) 
})
```



{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 1, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2015:00:10/30/15', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<javascript><node.js><azure><azure-storage><azure-blob-storage>', 'Title': "Can open blob returned by XMLHTTPRequest, but can't upload to Azure", 'ViewCount': 1011, 'id': 33438613, 'user_AboutMe': '<p>Enterprise Architect and Web Front End Developer || <a href="https://www.linkedin.com/in/kellyrusk/" rel="nofollow">LinkedIn</a> || <a href="http://thebitsthatbyte.com/" rel="nofollow">My Blog</a></p>\n\n<p>Specialties: </p>\n\n<p>Enterprise Content Management (ECM), Electronic Records Management (ERM), Web Content Management (WCM), Enterprise Architecture, Web Front End (WFE) Development, taxonomies, classification schemes, governance, business operations, systems engineering/administration, SharePoint, virtualization, project management, relational databases, international trade law and negotiation, crisis management, conflict resolution, lobbying, contract negotiation, vendor management.</p>\n\n<p>Application Programming/Scripting Languages/Web Services/APIs:</p>\n\n<ul>\n<li>HTML5/HTML, CSS3/CSS, JavaScript, jQuery, jQuery UI, AngularJS, Backbone.js, RequireJS, Bootstrap, JSON, REST, AJAX, CAML</li>\n<li>C#, ASP.NET Web Pages, ASP.NET Web Forms, ASP.NET MVC, Entity Framework, LINQ, XML</li>\n<li>PowerShell, SQL, ColdFusion</li>\n<li>SharePoint Client Object Model (CSOM), JavaScript Object Model (JSOM)</li>\n</ul>\n', 'user_AccountId': 3838188.0, 'user_DisplayName': 'Kode', 'user_Reputation': 2913.0, 'user_Views': 455.0, 'user_id': 3182042.0}}