40

I've generated a presigned S3 POST URL. Using the return parameters, I then pass it into my code, but I keep getting this error Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource..

Whereas on Postman, I'm able to submit the form-data with one attached file.

On PostMan, I manually entered the parameters enter image description here

The same parameters are then entered into my code. enter image description here

ngzhongcai
  • 1,483
  • 2
  • 22
  • 30

10 Answers10

48

You must edit the CORS Configuration to be public , something like:

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

enter image description here

kooskoos
  • 4,168
  • 1
  • 10
  • 22
Abdennour TOUMI
  • 76,783
  • 33
  • 229
  • 231
  • 3
    doesn't make sense, because I was able to upload via Postman. This is a POST request. Not a GET – ngzhongcai Dec 07 '17 at 07:15
  • Sorry, I mean CORS Configuration.. I updated the answer. Sorry again! – Abdennour TOUMI Dec 07 '17 at 07:17
  • 1
    Thank you for the tip. "Allowed Header: *" helped a little and I am getting some headway. What perplexed me is that the same thing worked in PostMan. But not on my code – ngzhongcai Dec 07 '17 at 07:34
  • 27
    @ngzhongcai fwiw, this works in postman and other test tools because postman is not a web site. CORS is a browser mechanism that prevents site A from making requests to site B (that's your bucket) unless site B agrees to accept the request from a viewer of site A via a "preflight check." The browser requires a CORS-friendly response when you're using one web site to access another but postman would not need/use/trigger this safety mechanism, because it's actually designed to protect both the user and site B from potentially malicious code on site A, and there is no site A under postman. – Michael - sqlbot Dec 07 '17 at 13:44
  • Thank you Michael! – ngzhongcai Dec 08 '17 at 04:34
  • @AbdennourTOUMI I have also faced the same issue, i could fix it by making allowedHeader to * . But I did not understand why we need to make it * and not any specific header as mentioned in https://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonRequestHeaders.html – Minions Aug 07 '18 at 04:03
  • 5
    This didn't work with AllowHeader * , did anyone fix this ? – Jeson Dias Dec 10 '18 at 04:41
  • 2
    Where to add? in S3 console / yourBucket / Permissions / CORS configuration and set h t t p s : //yourdomain.cloud in my case * was not enough... – oFace Jul 31 '19 at 10:08
17

Unable to comment so adding this here. Contains Harvey's answer, but in the form of a text to make it easy to copy.

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "PUT",
            "POST"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]
Pranav Joglekar
  • 301
  • 4
  • 5
8

I encountered this issue as well. My CORs configuration on my bucket seemed correct yet my presigned URLs were hitting CORs problems. It turns out my AWS_REGION for my presigner was not set to the aws region of the bucket. After setting AWS_REGION to the correct region, it worked fine. I'm annoyed that the CORS issue was such a red herring to a simple problem and wasted several hours of my time.

Math is Hard
  • 716
  • 11
  • 23
4

On my case I fixed it by having allowedMethods, and origins in S3. The menu is under the Permissions tab

enter image description here

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "PUT",
            "POST"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]
Harvey Kadyanji
  • 376
  • 4
  • 7
2

My issue was that for some reason - getSignedUrl returned a url like so:

https://my-bucket.s3.us-west-2.amazonaws.com/bucket-folder/file.jpg

I've removed the region part - us-west-2 - and that fixed it ‍♂️

So instead it is now

https://my-bucket.s3.amazonaws.com/bucket-folder/file.jpg

Gal Bracha
  • 16,762
  • 11
  • 64
  • 81
1

In my case I specifically needed to allow the PUT method in the S3 Bucket's CORS Configuration to use the presigned URL, not the GET method as in the accepted answer:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>PUT</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Conrad S
  • 125
  • 1
  • 6
0

For me,it was because my bucket name had a hyphen in it (e.g. my-bucket). The signed URL would replace the hyphen in the bucket name with an underscore and then sign it. So this meant two things:

  1. CORS wouldn't work because the URL technically wasn't correct
  2. I couldn't just change the underscore back to the hyphen because then the signature would be wrong when AWS validated the signed URL

I eventually had to rename my bucket to something without a hyphen (e.g. mybucket) and then it worked fine with the following configuration:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
John Galt
  • 1,274
  • 18
  • 22
0

My issue was I had a trailing slash (/) at the end of the domain in "AllowedOrigins". Once I removed the slash, requests worked.

echelon315
  • 57
  • 6
0

We have to specify only the required HTTP method. we were using the POST method for Presigned URL so removed the "GET" and "PUT" methods from "AllowedMethods"

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "POST"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]
0

I was getting similar CORS errors even with things properly configured.

Thanks to this answer, I discovered my Lambda@Edge that presigns was using a region that wasn't the right one for this bucket. (which was on us-east-1 for some default stack reason).

So I had to be explicit about the region when generating the presignedPost

reference: https://stackoverflow.com/a/13703595/11832970

  • It took me 1 whole day before getting this right. The CORS error was only confusing, and I should have focused on the 301 status – Raffael Campos Apr 20 '22 at 14:20