As the title implies, this is an interesting use case. I have an HTML5 Canvas that I am able to convert to a image. I am using AngularJS as the front end, with Node/Express on the backend for my site. Converting the HTML5 Canvas to an image works as intended and I am able to upload this to a separate Web Service using jQuery AJAX (not using Node/Express) as follows:
$scope.webService = function () {
var send = function (blob) {
var filename = 'Test.pdf';
var formdata = new FormData();
formdata.append('File1', blob, filename);
$.ajax({
url: 'http://awebservice.net/endpoint',
type: "POST",
data: formdata,
mimeType: "multipart/form-data",
processData: false,
contentType: false,
crossDomain: true,
success: function (result) {
console.log("Upload complete!");
},
error: function (error) {
console.log("Something went wrong!");
}
})
}
var canvasImage = document.getElementById("c");
if (!canvasImage.toBlob) {
var dataURL = canvasImage.toDataURL();
var bytes = atob(dataURL.split(',')[1])
var arr = new Uint8Array(bytes.length);
for (var i = 0; i < bytes.length; i++) {
arr[i] = bytes.charCodeAt(i);
}
send(new Blob([arr], { type: 'image/png' }));
}
else
canvasImage.toBlob(send);
}
I am using Node/Express in another scenario where I can upload an image to Azure via Node if I use a standard input form with a submit button. Here is the Node/Express code that uploads to Azure Blob Storage for an image manually uploaded by a user through an file input and submit button, where /upload is called on the form action of the HTML5 form:
app.post('/upload4', function (req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
var options = {
contentType: files.myfile.type,
metadata: { fileName: files.myfile.name }
};
blobSvc.createBlockBlobFromLocalFile('blob5', files.myfile.name, files.myfile.path, options, function (error, result, response) {
if (!error) {
// file uploaded
res.send('file uploaded!');
}
});
});
console.log(req);
});
However, I need to pass my converted HTML5 Canvas "behind the scenes" where users don't have to download and re-upload the HTML5 Canvas Image via a Web form, but rather on click, the Canvas is converted and the image is uploaded to Azure (see first example above for a working example using a different Web Service that doesn't use Node/Express that uploads an HTML5 Canvas converted to an image via jQuery AJAX). Essentially, since I am using Node/Express to manage Azure Blob Storage, I want the upload functionality that works in my jQuery AJAX example.
I was envisioning that I could pass the image data/variables back to Node/Express as follows:
AngularJS Front End Controller Code (tied to a ng-click button action named "upload()"):
$scope.upload = function () {
var canvasImage = document.getElementById("c");
var img = canvasImage.toDataURL("image/png");
var filename = 'Texture_0.png';
$http.post('/upload', { filename: filename, file: img }).success(function (data) {
console.log(data);
});
}
Node/Express Backend Code:
app.post('/upload', function (req, res) {
var filename = req.filename;
var file = req.file;
blobSvc.createBlockBlobFromLocalFile('mycontainer', filename, file, function (error, result, response) {
if (!error) {
console.log("Uploaded" + result);
// file uploaded
}
else {
console.log(error);
}
});
});
When I click the "magic button" to convert the Canvas to an image (image conversion works) and upload (upload doesn't work), I get a Node error as follows:
Error: Required argument blob for function createBlockBlobFromFile is not defined
I also logged "filename" and "file" to the Node console and got "undefined".
Client side I get a 500 Internal Server Error in the console of my browser. However, using the Network tab I dug deeper and saw that the "Request Payload" had the "file" base64 encoded and the "filename" as correct.
I largely suspect that I am not passing in the variables to Node/Express properly, and that is what is tripping up the Azure call. I am also wondering if since uploading an image via an input form works with Azure/Node, if I should somehow pass the converted Canvas as formdata but unsure how I would achieve this/should attempt it.
My question is, how do I pass the right variables/data so my canvas can be uploaded to Azure Blob Storage from AngularJS front end to Node/Express backend?