为什么有些浏览器会使Blob对象变空?如何预防呢?

时间:2018-04-05 00:33:38

标签: javascript jquery html ios blob

我正在使用Ruby on Rails5,并使用heroku爱好。然后我想让用户选择,裁剪并将图像从Javascript直接上传到亚马逊s3 like this article

我正在使用jQuery-file-upload和cropper.js。

下面的代码在我的MacBook Pro上的chrome中正常工作,但是,当涉及到iOS上的safari或safari,在iOS上使用chrome时,它会在s3上生成空文件(但具有正确的名称)。



$(function() {
  $('.directUpload').find("input:file").each(function(i, elem) {
    var fileInput    = $(elem);
    var form         = $(fileInput.parents('form:first'));
    var submitButton = form.find('input[type="submit"]');
    var progressBar  = $("<div class='bar'></div>");
    var barContainer = $("<div class='progress'></div>").append(progressBar);
    fileInput.after(barContainer);

    var lastData = null;
    submitButton.on('click', function(){
    $('form').submit(function(){
      return false;
      });
     // get cropped data
     $('#crop_img').cropper('getCroppedCanvas').toBlob(function (blob){
        lastData.files[0] = new File([blob], lastData.files[0].name);
        lastData.originalFiles[0] = lastData.files[0];
        lastData.submit();
      })
   });

    fileInput.fileupload({
    fileInput:       fileInput,
    url:             form.data('url'),
    type:            'POST',
    autoUpload:       false,
    formData:         form.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,
    acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
    // singleFileUploads: false,
    maxNumberOfFiles: 1,
    sequentialUploads: true,
    limitMultiFileUploads:1,
    limitConcurrentUploads: 1,

    add: function(e, data){
      if (data.files && data.files[0]) {
        var reader = new FileReader();
        reader.onload = function(e) {
          $('.preview').empty();
          $('.preview').append($('<img>').attr({// insert preview image
            src: e.target.result,
            id: "crop_img",
            title: data.files[0].name
          }));
          $('#crop_img').cropper() // initialize cropper on preview image
         };
       reader.readAsDataURL(data.files[0]);
       };

      lastData = data;
    },


    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', 'black').
        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   = '//' + form.data('host') + '/' + key;

      // create hidden field
      var input = $("<input />", { type:'hidden', name: fileInput.attr('name'), value: url })
      form.append(input);

      //delete submit event which is false
      $('form').off('submit');
      //and submit again
      $('.directUpload').submit();
    },

    fail: function(e, data) {
      submitButton.prop('disabled', false);

      progressBar.
        css("background", "red").
        text("Upload Failed!");
      }
    });
  });
});
&#13;
&#13;
&#13;

我认为这是因为这些浏览器不支持toBlob()方法,然后,根据this article,我在html文件中包含了canvas-to-blob.min.js。

但仍然无法发挥作用。

我也尝试了以下代码,而不是使用toBlob()方法(根据this article),它也不起作用....

&#13;
&#13;
//$('#crop_img').cropper('getCroppedCanvas').toBlob(function (blob){
       // lastData.files[0] = new File([blob], lastData.files[0].name);
        //lastData.originalFiles[0] = lastData.files[0];
        //lastData.submit();
 //     })
 
 //insetead of the code above, tried this...
      var canvas = $('#crop_img').cropper('getCroppedCanvas');
      var canvas_data = canvas.toDataURL();
      var blobData = dataURItoBlob(canvas_data);
      function dataURItoBlob(dataURI) {
         var binary = atob(dataURI.split(',')[1]);
         var array = [];
         for(var i = 0; i < binary.length; i++) {
             array.push(binary.charCodeAt(i));
         }
         return new Blob([new Uint8Array(array)], {type: 'image/jpeg'});
     }
     lastData.files[0] = new File([blobData], lastData.files[0].name);
     lastData.originalFiles[0] = lastData.files[0];
     lastData.submit();
   });
&#13;
&#13;
&#13;

我完全不知所措......有人帮我吗??

1 个答案:

答案 0 :(得分:0)

您应该通过AJAX将canvasElement.toDataURL()发送到PHP等服务器语言,您可以file_put_contents('tempfile.png', $dataURLajaxResult),然后您将拥有一个可以发送的文件,无论如何。