简体   繁体   中英

Dropzone client side resize with file upload to AWS pre-signed url

I implemented image file upload to an AWS s3 bucket with dropzone. It creates a pre-signed url and ultimately sends the image file to s3. I cannot get this to work in combination with the client side image resizing dropzone provides.

For s3 upload to work properly, I had to override sending , as explained here https://github.com/enyo/dropzone/issues/590 . Otherwise, it would send form data and I would get the image wrapped in ------WebKitFormBoundary...

This, from the link above is working:

  sending: function(file, xhr) {
    var _send = xhr.send;
    xhr.send = function() {
      _send.call(xhr, file);
    };
  }

However, I get problems when I try to combine the above approach with dropzone's client side image resize. As per the dropzone documentation, I specified:

  resizeWidth: 384,
  resizeHeight: 384,
  resizeMethod: 'contain',
  resizeQuality: 1.0,

Debugging the code, the resize functionality is called with the above settings. However, the file that arrives at sending is still the original file which has not been resized. I could not make out where the resized image would be stored.

I tried to change sending as follows:

sending (file, xhr) {
  var _send = xhr.send;

  this.options.transformFile.call(this, file, function (done) {
    console.log('done', done)
    xhr.send = function () {
      _send.call(xhr, done);
    }
  }

However, the result from the call to transformFile is a blob and, while the result looks resized, it is also wrapped as a form.

In summary, can I get the combination of resize with plain image upload to work, somehow? Is the resized image stored in a suitable place? Can my override of sending be changed to get this to function?

I just created an account to answer this since I've been trying to do the same thing for the last hours.

I was on the same track as what you did, except I removed the resizeWidth and resizeHeight params to prevent double processing, and called resizeImage instead.

After messing with logs for a while it hit me, it was a race condition! The function sending returned before xhr got modified. Specifically, in createThumbnail there is a FileReader that executes async. Your result was resized and wrapped because the xhr did not get changed at all, so it just executed the normal code path.

Thus, just calling the resizing function in xhr.send does the trick! 🎉🥳

Here is my working code:

sending: function(file, xhr) {
    var _send = xhr.send;
    var _this = this
    xhr.send = function () {
        _this.resizeImage(file, 500, 500, 'contain', function (done) {
            _send.call(xhr, done);
        })
    }
}

I asked the same on github and pkl's solution ( https://github.com/enyo/dropzone/issues/1840#issuecomment-538643878 ) worked for me:

xhr.send = formData => {
  // get the resized file in formData.get("file") vs file
  _send.call(xhr, formData.get("file"));
 };

also, joshmaines posted ( https://github.com/enyo/dropzone/issues/1840#issuecomment-545590304 ):

You could also override the process queue and implementing it in the thumbnail function instead: this.on('thumbnail', function(file, thumb) { file.thumbnail = thumb; this.processQueue(); });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM