Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CORS Amazon S3 file upload with jQuery Ajax request

I have scanned almost everything now and most people they're solution was simply to configure CORS on the S3 service, which doesn't do the trick for me. I must be missing something. Here it goes:

I'm trying to upload my files to Amazon S3 using an Ajax call on the client-side. I know my policy/signature are correct, since it works when I simply submit the form, but when I try and do an Ajax call with it I get the

Origin "my host" is not allowed by Access-Control-Allow-Origin. 

Error. My form:

<form id="fileform" action="https://mybucket.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
    <input type="hidden" name="key" value="mykey">
    <input type="hidden" name="AWSAccessKeyId" value="myaccesskey">
    <input type="hidden" name="acl" value="public-read">
    <input type="hidden" name="Content-Type" value="image/jpeg">
    <input type="hidden" name="policy" value="mypolicy">
    <input type="hidden" name="signature" value="mysignature">
  </form>

And in my CORS of the bucket I practically allow everything, because I'm desperate:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>HEAD</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

Choosing a file and submitting the form (either by clicking it or using jQuery) works like a charm, but performing an Ajax request with the serialized form gives me the error.

var form = $('#fileform');
$.ajax({
  url: "https://mybucket.s3.amazonaws.com/",
  type: 'post',
  crossDomain: true,
  dataType: 'xml',
  data: form.serialize()
});

I know this has something to do with the CORS rules, but as you can see they are set up. Therefore, anyone any idea what else might be wrong?

Thanks.

like image 941
Acek Avatar asked Oct 01 '13 18:10

Acek


2 Answers

You can add more HTML tags <input type="file" name="uploadFile" /> because without file you can not post the file data using serialize() method. And I suggest you use serializeArray() instead of form.serialize().

like image 89
Mehul Dudhat Avatar answered Oct 14 '22 09:10

Mehul Dudhat


Turns out that the error message displayed in the Chrome console had nothing to do with the actual error.

The problem was the jquery.serialize() does not save the file input because it is not supported in XMLHttpRequest (only in XMLHttpRequest 2). So the ajax request I was sending to S3 did not contain a file. Not sure why S3 was returning a CORS error, but once I switching to using FormData everything worked. Now I just have to figure out how to support IE 8 & 9... !

like image 36
Josh G Avatar answered Oct 14 '22 09:10

Josh G