简体   繁体   中英

Passing a Cordova camera.getPicture File to AWS S3 (JS SDK)

I am trying to pass an image created by Cordova's camera plugin to Amazon Web Service's S3.

In the past, I have used the HTML File API to create my S3 params, and been able to pass the file object. I can't directly link to how you do this, but there is an example on this page under the section 'example uses the HTML5 File API to upload a file on disk to S3'.

But this file has not been inserted by an input element, so I can't access anything like files[0] - the file is returned by Cordova either as a base64 or an available file location. So I am trying to figure out how I would replicate that action using Cordova information.

The solution I have worked off of is found here which results in the code below:

function onSuccess(imageData) {
   window.resolveLocalFileSystemURL(imageData, function(fileEntry) {
      fileEntry.file(function(file) {
         var reader = new FileReader();
         reader.onloadend = function(evt) {
            var theBody = btoa(evt.target._result);
            var 3_params = {
               Bucket: 'the-Bucket',
               Key: 'the-Key',
               ContentType: file.type,
               Body: theBody
            }
            ...other S3 SDK code...
         };
         reader.readAsDataURL(file);
      }
   }
}

This process works, but:

  1. I have to take _result (which is a base64) through btoa which means...
  2. It is pretty slow.
  3. It results in larger file sizes than I should need
  4. It also requires that I use getObject instead of getSignedURL
  5. When I get each object, I then have to put it through atob which means...
  6. If I have several objects to get things go VERY slow

What I would like to do is send the actual file object instead of messing with this base64 . Alternatively, I would take a better/smarter/faster way to handle the base64 to S3 process.

I was able to use the 'JavaScript Canvas to Blob' polyfill to create a blob from my Base64, and then send the returned Blob on to S3. Because it is now a blob instead of a coded string, I can use getSignedURL in the s3 APK to reference the image.

The only change from above is:

var theBody = btoa(evt.target._result);

Becomes

var theBody = window.dataURLtoBlob(evt.target._result);

https://github.com/blueimp/JavaScript-Canvas-to-Blob

For those who find this, there is a better way since the new features introduced in XMLHttpRequest and now we can use readers and Blob as a source.

The initial code now could be written using FileReader.readAsArrayBuffer method and passing Blob object as the body source:

function onSuccess(imageData) {
  window.resolveLocalFileSystemURL(imageData, function(fileEntry) {
    fileEntry.file(function(file) {
      var reader = new FileReader();
        reader.onloadend = function(evt) {
          var blob = new Blob([new Uint8Array(this.result)], { type: file.type });
          var 3_params = {
            Bucket: 'the-Bucket',
            Key: 'the-Key',
            ContentType: file.type,
            Body: blob
         }
         ...other S3 SDK code...
       };
       reader.readAsArrayBuffer(file);
     }
   }
 }

More info can be found at Cordova Blog - Transition off of cordova-plugin-file-transfer

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