3

I'm trying to upload an image taken with

Webcam js

directly to Amazon S3

var dataUri = Webcam.snap();
var raw = window.atob(dataUri.replace(/^data\:image\/\w+\;base64\,/, ''));

and after I get the policy (which is correct) I do this

$.ajax({
        type: 'POST',
        url: amazonUploadUrl,                                
        data: {
              file: raw,
              contentType: "image/jpeg",
              key: key,
              AWSAccessKeyId: awsAccessKey,
              acl: "public-read",
              policy: policy,
              signature: signature,
              name: "",
              Filename: filename
              },
              dataType: "",
              success: function (r1) {

              }
        });

I've tried sending the encoded image, the decoded image, I've tried modifying the headers. All I keep getting is this

XMLHttpRequest cannot load 'amazon s3 bucket url'. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'my local domain' is therefore not allowed access.

I've added the CORS info on the Amazon bucket. I'm already uploading images to that bucket using plupload. I've also uploaded images from a standard without using ajax. I just can't seem to get this to work.

Any ideas? Thanks

PS: I've also tried using

jquery webcam plugin

With the same result

Mihai
  • 2,740
  • 31
  • 45

1 Answers1

3

You'll need to use the javascript FormData object and native XMLHttpRequest methods to post the data directly to s3. I've tried to do the exact same thing this morning with jQuery and ran into that error message, but native javascript APIs work.

I have a feeling jQuery isn't using CORS by default or is sending across a the wrong header somewhere.

This answer shows how to convert to a format S3 can understand, which may not be necessary in your case.

This should get you started on the form data part:

var fd = new FormData();
fd.append("contentType", "image/jpeg");
fd.append("key", key);
fd.append("AWSAccessKeyId", awsAccessKey);
fd.append("acl", "public-read");
fd.append("policy", policy);
fd.append("signature", signature);    
fd.append('filename', "");
fd.append('file', raw);

var xhr = new XMLHttpRequest();
xhr.open('POST', amazonUploadUrl);

xhr.addEventListener('load', function(e) {
    console.log('uploaded!', e)  // Successful upload!
});

// Optionally bind to other xhr events, like error, progress, or abort.
// Using native XHR2 is nice because the progress event works and you
// can tack on upload progress counters.
xhr.send(fd);
Community
  • 1
  • 1
ajm
  • 19,795
  • 3
  • 32
  • 37
  • Thanks for the answer. Once quick question: does this also work in Internet Explorer 8 and 9 ? :) – Mihai Mar 27 '14 at 07:57
  • And while we're on the subject of uploading files to Amazon S3, have you by any chance used plupload (or jquery upload) to upload files to S3 ? for some reason neither of these solution work for me in Internet Explorer 8 or 9. Any ideas ? – Mihai Mar 27 '14 at 08:00
  • No, this is definitely not IE <= 9 friendly. :) I've used SWFUpload (https://code.google.com/p/swfupload/) to upload to s3 in IE <= 9. It's outdated (and I believe is no longer in active development), but it works. I don't think `atob` is supported in oldIE, either, so that would be a bit of trouble for you, too. – ajm Mar 27 '14 at 13:50