Replies: 2 comments
-
I wish you would have put the complete code here to make this easier to follow. That said, thank you much for sharing anything at all! |
Beta Was this translation helpful? Give feedback.
-
This works well. By "accept: fetchPreSignedUrlFromBE)", you can retrieve s3 pre-signed url from the BE server, and that value is passed by the url flag. new Dropzone(document.querySelector('#myDropzone'), {
url: (files) => {
return `${files[0].dynamicUploadUrl}`;
},
accept: fetchPreSignedUrlFromBE,
method: "PUT",
headers: {
"Content-Type": 'image/jpeg'
},
init: function () {
this.on("sending", function (file, xhr, formData) {
const _send = xhr.send;
xhr.send = function () {
_send.call(xhr, formData.get("file"));
};
});
}
}
const fetchPreSignedUrlFromBE = (file, done) => {
// fetch pre signed url from BE
file.dynamicUploadUrl = response.preSignedUrl
done();
} Thanks for sharing. |
Beta Was this translation helpful? Give feedback.
-
This is probably not the best place to put this, but seeing as I have spend the last day and change trying to get this to work, I thought I would put down my solution, in-case some other poor internet user runs into this as well.
I'll try to keep this short..
Task: Use a preSigned URL with DropZone (seems simple enough :D)
To start with, I'm not going to boiler plate the URL request here, there are many topics on how to generate this, we are using Node and the s3 module, generally speaking though, your basic flow is going to be
Now, this will be a YMMV on this, we use Linode object store (s3 compatible API) and what we ran into was a mixture of 'Access denied' to 'mismatchkeys' etc. Pulling my hair out for a solid day on this.
What finally worked for us was that we had to pass over in the headers the returned parameters of the signedURL, here is a crude 'but works' snippet of what we did
`//we need to prepare the URL now
let s3URL = res.url.split("?");
//now, we split the string again
s3URL = s3URL[1].split("&");
//now we loop over the array to contruct the headers
s3URL.forEach((item)=>{
let tempitem = item.split("=")
Basically, what we do here is take the URL, split it in two, then split the querystring paramater and loop over it. With each loop, we add the header to the DropZone options. ( I know, this can can probably be more error tolerant, so update it as needed, but after a day on this, I simply don't care enough at the moment )
One fun thing, and I'm sure you noticed is we do a check for content-type in the loop, and choose a different value here, well, for some reason, if you use the 'encoded' type it wont work ( another fun one, again, you could just convert the string to unencoded etc, but I'm over it at the moment :D )
So, after the loop has finished you should have all the needed header in dropzone to pass over, now you need to update the URL with the returned URL of the signed request. This can be done by updating the 'options' again
[dzObject].options.url = res.url;
Cool, almost ready, next we need to tell DZ to continue processing using
[dzObject.processQueue();
Now, this will send the request to your object store, it will probably work, but the file wont because DZ is not sending over the raw binary, to do this, you need to hijack the sending of the xhr request. This can be done via the event or in the init isself
sending: function(file, xhr,formData) { var _send = xhr.send; xhr.send = function() { _send.call(xhr, formData.get("file")); }; }
We do this in the init, so adding this there will cause it to send just the raw form data. This call also will honor any resizes you do because we grab the file from the formdata as well.
At this point, your files should upload correctly.
Apologies for the barebones, not perfect but working write up and hope it may help somebody in the future ( or maybe even myself once I forget how to do this in the future :D ).
Beta Was this translation helpful? Give feedback.
All reactions