17

I'm trying to upload a picture to my S3 bucket. I'm using AngularJS v1.2.13. When I use the simple case as displayed in their docs (submit form with action tag) everything works fine. However, if I want to do it the Angular way with ng-click Angular sends an OPTIONS request instead of a POST request.

The following is the Service code, it first goes to the server to get a signature (I know that part is fine) then tries to POST with everything.

myServices.factory('s3', function($http) {
    var service = {};

    service.upload = function(fileName) {

        return $http(
            {
                method:"POST",
                url: "sign",
                data: { "fileName": fileName }
            }
        ).then(
            function(result) {
                // success
                //resolve the promise as the data
                var data = result.data;
                var url = "https://" + data.bucket + ".s3.amazonaws.com/";

                return $http.post(url, {
                    "key": data.key,
                    "AWSAccessKeyId": data.awsKey,
                    "acl": data.acl,
                    "policy": data.policy,
                    "signature": data.signature,
                    "Content-Type": "image/jpeg",
                    "success_action_redirect": "http://localhost:3000/s3Uploaded"
            }).then(
            function(response) {
                // success
                console.log("s3.upload, success: ");
                console.log(response);
            },
            function(response) { 
                // failed
                console.log("s3.Upload, fail: ");
                console.log(response);
            }
        );

    },
        function(response) { 
            // failed
            console.log("s3.sign, fail: ");
            console.log(response);
        }
    );
};

return service;
});

What am I doing wrong?

McMeep
  • 688
  • 2
  • 8
  • 13
  • It's due to the CORS policy and is done by the browser automatically, nothing wrong there. – aUXcoder Jul 02 '19 at 19:40
  • You are missing to configure the cors policies in your s3 bucket, to allow the domain your are using. – Pierre Emmanuel Lallemant Nov 14 '19 at 18:41
  • 1
    [Teena Pamecha](https://stackoverflow.com/users/7364271) posted an [Answer](https://stackoverflow.com/a/66289282) saying "Maybe you did not Configure CORS for an Amazon S3 Bucket or enable core origin [Configure CORS for an Amazon S3 Bucket](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/cors.html) [How Do I Configure CORS on My Bucket?](https://docs.aws.amazon.com/AmazonS3/latest/userguide/cors.html#how-do-i-enable-cors)" – Scratte Feb 20 '21 at 10:31

4 Answers4

1

Angular is sending a preflight request, so if you can go back to your first plan, do that!

https://stackoverflow.com/a/44343635/1308736

https://stackoverflow.com/a/22968724/1308736

ajd
  • 423
  • 4
  • 11
0

In S3 headers in CORS add header:

Access-Control-Allow-Origin: *

hjdud
  • 21
  • 3
0

Server will check either you should be allow to post some data on server itself or not as per the

cross origin resource sharing policy

that is quite normal that you are getting options request. your ApI server should have configured to allow request from your domain to work correctly.

0

You need add a new CORS Policy configuration into own AWS S3 bucket

https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/cors.html

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <CORSRule>
    <AllowedOrigin>https://example.org</AllowedOrigin>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
    <ExposeHeader>ETag</ExposeHeader>
    <ExposeHeader>x-amz-meta-custom-header</ExposeHeader>
  </CORSRule>
</CORSConfiguration>
Pablo M.
  • 494
  • 7
  • 14