I would like to use dropzone.js to upload files directly to Azure Blob Storage, with SAS (example here) to keep the files private.
As I understand it, the workflow would be:
- The user chooses a file
- The dropzone
processing
event fires. In the event handler, I call a method on my site's API which creates an Azure Blob URI to upload to, including the SAS query string - The dropzone upload URL is set to the "secured" blob URL
- The upload begins
I have found the following wiki article showing how to set the dropzone URL dynamically ()
Dropzone.options.myDropzone = {
init: function() {
this.on("processing", function(file) {
// I need to do an async call here, to get the URL...
this.options.url = "/some-other-url";
});
}
};
The problem is that the above example is synchronous. How can I delay the upload until the URL has been requested from my web api asynchronously?
Thanks
I would like to use dropzone.js to upload files directly to Azure Blob Storage, with SAS (example here) to keep the files private.
As I understand it, the workflow would be:
- The user chooses a file
- The dropzone
processing
event fires. In the event handler, I call a method on my site's API which creates an Azure Blob URI to upload to, including the SAS query string - The dropzone upload URL is set to the "secured" blob URL
- The upload begins
I have found the following wiki article showing how to set the dropzone URL dynamically (https://github./enyo/dropzone/wiki/Set-URL-dynamically)
Dropzone.options.myDropzone = {
init: function() {
this.on("processing", function(file) {
// I need to do an async call here, to get the URL...
this.options.url = "/some-other-url";
});
}
};
The problem is that the above example is synchronous. How can I delay the upload until the URL has been requested from my web api asynchronously?
Thanks
Share Improve this question asked Feb 17, 2016 at 12:02 Matt WilsonMatt Wilson 8,3198 gold badges37 silver badges57 bronze badges 1- Great question! We need to do this as well. Before I dig too much into this library, do you mind letting me know if you were successful in using Dropzone to handle the Azure uploads? Were there any challenges along the way? With the URL I assume you can have the upload filename be something other than the original filename correct? – John Livermore Commented Jul 28, 2016 at 3:47
2 Answers
Reset to default 4May be I am a bit late with answer
Use predefined SAS
Just save it in form
element with data-sas
attribute while rendering a page. The only drawback I see — your SAS could expire if page haven’t refreshed for a while. This is a part from my working code (other variants are from my head)
Dropzone.options.myDropzone = {
method: "PUT",
headers: {"x-ms-blob-type": "BlockBlob"},
sending: (file, xhr) => {
// To send file without wrappintng it to multipart/form-data,
// Azure won’t unwrap it
const _send = xhr.send;
xhr.send = () => { _send.call(xhr, file) };
},
init: function() {
const dz = this,
action = dz.element.action,
sas = dz.element.dataset.sas;
dz.on("processing", (file) => {
dz.options.headers["Content-Type"] = file.type;
dz.options.url = `${action}/${file.name}?${sas}`;
})
},
}
Use async call in Dropzone’s init
Dropzone.options.myDropzone = {
autoProcessQueue: false, // To prevent automatic auploading before getting SAS
acceptedFiles: ".xls,.xlsx",
method: "PUT",
headers: {"x-ms-blob-type": "BlockBlob"},
sending: (file, xhr) => {
// To send file without wrappintng it to multipart/form-data,
// Azure won’t unwrap it
const _send = xhr.send;
xhr.send = () => { _send.call(xhr, file) };
},
init: function() {
let sas = null;
const dz = this,
xhr = new XMLHttpRequest();
xhr.addEventListener("load",
(event) => {
sas = getSasFromEvent(event);
dz.options.autoProcessQueue = true;
dz.processQueue();
}, true);
xhr.open("GET", "/get-sas");
xhr.send();
dz.on("processing", (file) => {
dz.options.headers["Content-Type"] = file.type;
dz.options.url = `${action}/${file.name}?${sas}`;
})
},
}
Run Dropzone after you’ve got a SAS asynchrouniosly
See Create dropzones programmatically
You could try a synchronous ajax call using jQuery.
function GetUrl() {
var url = "";
$.ajax({
async: false,
success: function(data) {
url = data;
}
// Other opts
});
return url;
}
Dropzone.options.myDropzone = {
init: function() {
this.on("processing", function(file) {
this.options.url = GetUrl();
});
}
};