简体   繁体   中英

jQuery-file-upload: how to send separate request per each file size

I use jQuery File Upload widget to make direct upload from client-side to AWS S3. CORS and pre-signed POST are used.

If upload original file or file resized once it works fine. Same works for multiple select.

Until I add resized versions. Resizing is maid through processQueue of jQuery-File-Upload.

If try to Upload multiple resolutions of one image S3 return error message "POST requires exactly one file upload per request."

How can I send separate XHR request per each file size?

singleFileUploads option is true by default but it works only for different files not for file versions of each file.

I my case i have following structure:

file_input.element[0]
  data.files[0] - original size
  data.files[1] - thumbnail
file_input.element[1]
  data.files[0] - original size
  data.files[1] - thumbnail
...

Guess I need to use Callback Options but already 3 days can not find how to do. Thanks in advance.

Main js looks like this:

$(document).on('turbolinks:load', function() {
  $(function() {
    var submitButton = $('#fileupload').find('input[type="submit"]');
    var progressBar  = $("<div class='bar'></div>");
    var barContainer = $("<div class='progress'></div>").append(progressBar);
    $('#fileupload').after(barContainer);

    $('#fileupload').fileupload({
      url:             $('#fileupload').data('url'),
      type:            'POST',
      autoUpload:       true,
      formData:         $('#fileupload').data('form-data'),
      paramName:        'file', // S3 does not like nested name fields i.e. name="user[avatar_url]"
      dataType:         'XML',  // S3 returns XML if success_action_status is set to 201
      replaceFileInput: false,
      singleFileUploads: false,
      processQueue: [
          {
              action: 'loadImage',
              fileTypes: /^image\/(gif|jpeg|png)$/,
              maxFileSize: 20000000 // 20MB
          },
          {
              action: 'resizeImage',
              maxWidth: 1920,
              maxHeight: 1200
          },
          {action: 'saveImage'},
          {action: 'duplicateImage'},
          {
              action: 'resizeImage',
              maxWidth: 1280,
              maxHeight: 1024
          },
          {action: 'saveImage'},
      ],

      progressall: function (e, data) {
        var progress = parseInt(data.loaded / data.total * 100, 10);
        progressBar.css('width', progress + '%')
      },
      start: function (e) {
        submitButton.prop('disabled', true);

        progressBar.
          css('background', 'green').
          css('display', 'block').
          css('width', '0%').
          text("Loading...");
      },
      done: function(e, data) {
        submitButton.prop('disabled', false);
        progressBar.text("Uploading done");

        // extract key and generate URL from response
        var key   = $(data.jqXHR.responseXML).find("Key").text();
        var url   = '//' + $('#fileupload').data('host') + '/' + key;

        // create hidden field
        var input = $("<input />", { type:'hidden', name: $('#fileupload').attr('name'), value: url })
        $('#fileupload').append(input);
      },
      fail: function(e, data) {
        submitButton.prop('disabled', false);

        progressBar.
          css("background", "red").
          text("Failed");
      }
    });
    $.blueimp.fileupload.prototype.processActions.duplicateImage = function (data, options) {
        if (data.canvas) {
            data.files.push(data.files[data.index]);
        }
        return data;
    };
  });
});

form.data('url') and for.data('form-data') - prepared in controller through pre-signed POST generated from the AWS ruby gem.

My own solution was not nice but it works - add submit callback:

  singleFileUploads: true,
  submit: function (e, data) {
    if (data.files.length > 1) {
      original_file = data.files[1]
      thumbnail = data.files[0]
      thumbnail.name = 'thumbnail_'+thumbnail.name
      data.files = [thumbnail];
      data.submit();
      data.files = [original_file]
    }
  }

Hope in future someone will write a correct way to do.

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