jqueryamazon-s3jquery-file-uploadjquery-fileupload-rails

jQueryFileUpload - S3 - Empty file upload result error


I'm trying to set up S3 direct upload with the jQuery File Upload library. I'm using their latest version, and here is how I'm initializing the plugin:

$(function() {
  $("#s3-uploader").data(
    "key",
    $("#s3-uploader")
      .find("input[name='key']")
      .val()
  );
  var settings = { path: "" };
  $("#s3-uploader").fileupload({
    limitConcurrentUploads: 1,
    acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
    dataType: "xml",
    paramName: "file",
    formData: function(form) {
      var data, fileType, key;
      data = form.serializeArray();
      fileType = "";
      if ("type" in this.files[0]) {
        fileType = this.files[0].type;
      }
      data.push({
        name: "content-type",
        value: fileType
      });
      key = $("#s3-uploader")
        .data("key")
        .replace("{timestamp}", new Date().getTime())
        .replace("{unique_id}", this.files[0].unique_id);
      data[1].value = settings.path + key;
      if (!("FormData" in window)) {
        $("#s3-uploader")
          .find("input[name='key']")
          .val(settings.path + key);
      }
      return data;
    }
  });
});

And here are the extra form data I'm sending to satisfy S3 requirements:

<input name="utf8" type="hidden" value="✓">
<input type="hidden" name="key" id="key" value="uploads/{timestamp}-{unique_id}-4c9ded19e2649ab92c6d37e6e30e679a/${filename}">
<input type="hidden" name="acl" id="acl" value="public-read">
<input type="hidden" name="AWSAccessKeyId" id="AWSAccessKeyId" value="<KEY>">
<input type="hidden" name="policy" id="policy" value="<POLICY>">
<input type="hidden" name="signature" id="signature" value="JOK4zvx/jAJbUXHzWGGUJ8pxk5E=">
<input type="hidden" name="success_action_status" id="success_action_status" value="201">
<input type="hidden" name="X-Requested-With" id="X-Requested-With" value="xhr">

The upload happens correctly and the file is available in S3, but then the upload throws this error: Empty file upload result

Enter image description here

The response from S3 is an XML document:

<PostResponse><Location>htps://my-bucket.s3-accelerate.amazonaws.com/uploads%2F1583345823865-undefined-4c9ded19e2649ab92c6d37e6e30e679a%2F_102035t8.JPG</Location><Bucket>my-bucket</Bucket><Key>uploads/1583345823865-undefined-4c9ded19e2649ab92c6d37e6e30e679a/_1020358.JPG</Key><ETag>"c77b13bec857d9470f360b363f7fb045"</ETag></PostResponse>

How do I make jQuery File Upload handle this response from S3 and consider it as success and parse the S3 URL?


Solution

  • It looks like jQuery File Upload does not handle this situation on its own.

    I.e., it does not parse the XML document returned by S3. I borrowed some code from the s3_direct_upload gem to get the job done. You can find it in file s3_direct_upload.js.coffee.