ChatGPT解决这个技术问题 Extra ChatGPT

S3 - Access-Control-Allow-Origin Header

Did anyone manage to add Access-Control-Allow-Origin to the response headers? What I need is something like this:

<img src="http://360assets.s3.amazonaws.com/tours/8b16734d-336c-48c7-95c4-3a93fa023a57/1_AU_COM_180212_Areitbahn_Hahnkoplift_Bergstation.tiles/l2_f_0101.jpg" />

This get request should contain in the response, header, Access-Control-Allow-Origin: *

My CORS settings for the bucket looks like this:

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

As you might expect there is no Origin response header.

One thing that's missing from this is: Access-Control-Allow-Origin
In my case it wasn't necessary, however, it will seem as though it didn't work at first due to cloudfront cache if you are using that.

O
Owen Blacker

Usually, all you need to do is to "Add CORS Configuration" in your bucket properties.

https://i.stack.imgur.com/acAvH.png

The <CORSConfiguration> comes with some default values. That's all I needed to solve your problem. Just click "Save" and try again to see if it worked. If it doesn't, you could also try the code below (from alxrb answer) which seems to have worked for most of the people.

<?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>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration> 

For further info, you can read this article on Editing Bucket Permission.


It seems to be possible. Try reading the link above (in the answer) or go straight ahead to this one: docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTcors.html
Thank you. Simply clicking save on this allowed my fonts to load.
I notice it works sometimes and other times I get the browser error still after editing this. Not sure if its CloudFlare or the S3.
You may need to add HEAD to the AllowedMethods
Doesn't work for me. Still no 'Access-Control-Allow-Origin' header in the response of either HEAD or GET requests.
c
coderVishal

S3 now expects the rules to be in Array Json format.

You can find this in s3 bucket -> Permissions then -> scroll below -> () Cross-origin resource sharing (CORS)

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "HEAD"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [],
        "MaxAgeSeconds": 3000
    }
]

Thanks a lot. Is this even described somewhere in a documentation ? I cannot see anything in the latest: docs.aws.amazon.com/AmazonS3/latest/dev/…
Not sure, if this was there a few days ago, but as of this writing the docs show: Important In the new S3 console, the CORS configuration must be JSON.
This is the most up to date solution, AWS had automatically updated my CORS config missing out the "HEAD" property which broke my site. Nice one for this!
This should be the accepted answer. since the old accepted answer is outdated now.
It's wild that I had to scroll this far down to get this answer. Please upvote, this is the correct solution!
O
Owen Blacker

I was having a similar problem with loading web fonts, when I clicked on 'add CORS configuration', in the bucket properties, this code was already there:

<?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>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration> 

I just clicked save and it worked a treat, my custom web fonts were loading in IE & Firefox. I'm no expert on this, I just thought this might help you out.


Thanks! This did it for me. I got as far as clicking 'add CORS configuration', but didn't realize I had to click 'save' because I thought I was looking at the default config. D'oh.
I had to set <AllowedHeader>*</AllowedHeader> for it to work (better to make a new rule for your site only when doing this)
@parliament had the magic there, as all other above settings didn't do the trick until the was set to a wildcard. Hurrah.
I went to CORS settings and found the same settings in there, but * became active when I hit the save. It wasnt before.
That was it, click Save
e
eremzeit

If your request doesn't specify an Origin header, S3 won't include the CORS headers in the response. This really threw me because I kept trying to curl the files to test the CORS but curl doesn't include Origin.


i was looking over the internet since 2 , weeks all the articles and answers was talking about changing the S3 CORS configurations i did as they said but no changes on the response , until i saw your answer it make sense to me, i tested it using postman and its working! so thank you very much
Anyone knows how can I change headers of an img tag? I can't send different headers, the browser sends the request
OMG is it documented anywhere?
It is :) docs.aws.amazon.com/AmazonS3/latest/dev/… > Verify that the request has the Origin header.If the header is missing, Amazon S3 doesn't treat the request as a cross-origin request, and doesn't send CORS response headers in the response.
Is there any way to force the CORS header to be included without specifying Origin?
S
Senica Gonzalez

@jordanstephens said this in a comment, but it kind of gets lost and was a really easy fix for me.

I simply added HEAD method and clicked saved and it started working.

* GET HEAD 3000 Authorization


Yep. This fixes the "No 'Access-Control-Allow-Origin' header" error in Chrome when GET-ing things like fonts from AWS S3.
Yes! Thank you so much. Allowing HEAD method did the trick.
C
Community

This is a simple way to make this work.

I know this is an old question, but still is hard to find a solution.

To start, this worked for me on a project built with Rails 4, Paperclip 4, CamanJS, Heroku and AWS S3.

You have to request your image using the crossorigin: "anonymous" parameter.

    <img href="your-remote-image.jpg" crossorigin="anonymous"> 

Add your site URL to CORS in AWS S3. Here is a refference from Amazon about that. Pretty much, just go to your bucket, and then select "Properties" from the tabs on the right, open "Permissions tab and then, click on "Edit CORS Configuration". Originally, I had < AllowedOrigin> set to *. Just change that asterisk to your URL, be sure to include options like http:// and https:// in separate lines. I was expecting that the asterisk accepts "All", but apparently we have to be more specific than that.

This is how it looks for me.

https://i.stack.imgur.com/wFYQK.png


unlike the accepted answer, this actually works ! Even ClaudFront CDN loading this S3 is replicating these headers. Thank you dude Saved me couple of hours !
Thanks to @Kunal's link. CloudFront adds a layer of complexity to this equation.
I had gotten as far as the MDN docs on <img>, but I put only crossOrigin="true" by mistake. THANK YOU!
Wow this actually did the trick for me! I'm able to use it on localhost and I can even use the asterisk, the key was to just add crossorigin="anonymous" to my html element :D
d
dansch

See above answers. (but I had a chrome bug too)

Don't load and display the image on the page in CHROME. (if you are going to later create a new instance)

In my case, I loaded images and displayed them on the page. When they were clicked, I created a new instance of them:

// there is already an html <img /> on the page, I'm creating a new one now
img = $('<img crossorigin />')[0]
img.onload = function(){
  context.drawImage(img, 0, 0)
  context.getImageData(0,0,w,h)
}
img.src = 'http://s3.amazonaws.com/my/image.png'; // I added arbitrary ?crossorigin to change the URL of this to fix it

Chrome had already cached another version and NEVER tried to re-fetch the crossorigin version(even if I was using crossorigin on the displayed images.

To fix, I added ?crossorigin to the end of the image url(but you could add ?blah, it's just arbitrary to change the cache status) when I loaded it for canvas.. Let me know if you find a better fix for CHROME


Caching proved to be my problem too (after I'd tried the accepted answers). Thanks for this.
Also had the cache issue on Chrome. Easy fix: Tools / Settings > Clear Browsing Data... > Cached Images and Files Although another solution may be required for users who might face this issue.
Thanks for this answer! I had the same problem with Chrome and I didn't find answer.
All people need to try this if has problems with CORS!! Save my day!
t
tilde

I'll just add to this answer–above–which solved my issue.

To set AWS/CloudFront Distribution Point to torward the CORS Origin Header, click into the edit interface for the Distribution Point:

https://i.stack.imgur.com/2JAj3.png

Go to the behaviors tab and edit the behavior, changing "Cache Based on Selected Request Headers" from None to Whitelist, then make sure Origin is added to the whitelisted box. See Configuring CloudFront to Respect CORS Settings in the AWS Docs for more.

https://i.stack.imgur.com/IGvqg.png


What allowed HTTP methods must you set?
You mean like GET, POST, DELETE, etc...? Where are those being requested?
Can you re-phrase your question please so I can understand whether you are referring to the cf web form, or the application that is requested the s3 resource? If the former, there is a HTTP methods option that is mentioned in the docs here docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/…
Seems like you were asking what HTTP Request Methods must be set within AWS. And to that question, I don't see that one needs to be set anywhere. If you are talking about within the application requesting the resource, I believe you would just request the file by it's url string: ie an image, video, audio file.
That was the missing piece! thank you! I tried all the answers above this one and only after whitelisting these headers it worked for me on localhost
v
veuncent

I was having similar problems loading 3D models from S3 into a javascript 3D viewer (3D HOP), but strangely enough only with certain file types (.nxs).

What fixed it for me was changing AllowedHeader from the default Authorization to * in the CORS config:

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

Needed to set <AllowedHeader>*</AllowedHeader> just like this with an asterisk for Chrome in October 2017. Thank you so much! (Also, don't forget to clear browser cache after setting).
Small point - I don't think you need to change the AllowedHeader. I was also having the same issue here, but it turns out it was the browser caching the previous response (MaxAgeSeconds). In DevTools Settings, you can ignore the cache while the console is open. Once this was done, it started working for me
AllowedHeader>*< definitely fixed this issue for me. It may only apply when the request is sent via a particular xhr library? I'm using Axios and found it necessary.
T
Tonio

Like others have stated, you first need to have the CORS configuration in your S3 bucket:

<CORSConfiguration>
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod> <!-- Add this -->
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>

But in my case after doing that, it was still not working. I was using Chrome (probably the same problem with other browsers).

The problem was that Chrome was caching the image with the headers (not containing the CORS data), so no matter what I tried to change in AWS, I would not see my CORS headers.

After clearing Chrome cache and reloading the page, the image had the expected CORS Headers


Thank you! This caching issue was driving me insane. For anyone wondering how to clear the cache easily on Chrome (version 73), right click the reload button and choose 'Empty Cache and Hard Reload'. Then you'll see the effect of any changes you've made to your S3 CORS within < 5 seconds. (Maybe faster - that's just how long it takes me to switch browser tabs.)
THIS was my problem. My bucket had the appropriate CORS configuration, my browser was simply being wonderfully efficient 🤪Thank you.
s
shim

I tried all answers above and nothing worked. Actually, we need 3 steps from above answers together to make it work:

As suggested by Flavio; add CORS configuration on your bucket: * GET On the image; mention crossorigin: Are you using a CDN? If everything works fine connecting to origin server but NOT via CDN; it means you need some setting on your CDN like accept CORS headers. Exact setting depends on which CDN you are using.


Thanks the CDN part is very important, could you add details of what is needed at the CDN level?
B
Brad

I arrived at this thread, and none of the above solutions turned out to apply to my case. It turns out, I simply had to remove a trailing slash from the <AllowedOrigin> URL in my bucket's CORS configuration.

Fails:

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

Wins:

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

I hope this saves someone some hair-pulling.


C
Christian Saavedra

First, activate CORS in your S3 bucket. Use this code as a guidance:

<CORSConfiguration>
 <CORSRule>
   <AllowedOrigin>http://www.example1.com</AllowedOrigin>

   <AllowedMethod>PUT</AllowedMethod>
   <AllowedMethod>POST</AllowedMethod>
   <AllowedMethod>DELETE</AllowedMethod>

   <AllowedHeader>*</AllowedHeader>
 </CORSRule>
 <CORSRule>
   <AllowedOrigin>http://www.example2.com</AllowedOrigin>

   <AllowedMethod>PUT</AllowedMethod>
   <AllowedMethod>POST</AllowedMethod>
   <AllowedMethod>DELETE</AllowedMethod>

   <AllowedHeader>*</AllowedHeader>
 </CORSRule>
 <CORSRule>
   <AllowedOrigin>*</AllowedOrigin>
   <AllowedMethod>GET</AllowedMethod>
 </CORSRule>
</CORSConfiguration>

2) If it still not working, make sure to also add a "crossorigin" with a "*" value to your img tags. Put this in your html file:

  let imagenes = document.getElementsByTagName("img");
    for (let i = 0; i < imagenes.length; i++) {
      imagenes[i].setAttribute("crossorigin", "*");

P
Pawel Furmaniak

Set CORS configuration in Permissions settings for you S3 bucket * GET 3000 Authorization S3 adds CORS headers only when http request has the Origin header. CloudFront does not forward Origin header by default You need to whitelist Origin header in Behavior settings for your CloudFront Distribution.


P
Pablo García Miranda

I fixed it writing the following:

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

Why <AllowedHeader>*</AllowedHeader> is working and <AllowedHeader>Authorization</AllowedHeader> not?


D
DIWAKAR

This configuration solved the issue for me:

<?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>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <ExposeHeader>ETag</ExposeHeader>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

I see very little difference between this configuration and the configurations of many other answers in this question. Was any attempt made to use the older answers' configurations before posting this configuration?
P
Prem Chavhan

Please also clean cache of the browser after updating CORS configuration. Mine worked after cleaning cache while working with strapi


also check dev.to/tomspencerlondon/… this blog very useful
HI @PremChavhan - welcome to stack overflow - looks like most of whats in this answer is perhaps already covered in the 26 other (highly rated) answers. If you think your answer identifies something new perhaps edit the best rated answer that is relevant to it (or add a comment) to bring this new idea to the fore-front.
M
Mich. Gio.

fwuensche "answer" is corret to set up a CDN; doing this, i removed MaxAgeSeconds.

<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedHeader>Authorization</AllowedHeader>
</CORSRule>

h
hackel

In the latest S3 Management Console, when you click on the CORS configuration on the Permissions tab, it will show a default sample CORS configuration. This configuration is not actually active, however! You have to first click save in order to activate CORS.

It took me way too long to figure this out, hopefully this will save someone some time.


P
Philip Murphy

Warning - Hack.

If you use S3Image to display an image and subsequently try to get it via fetch, maybe to insert it into a PDF or do some other processing, be warned that Chrome will cache the first result that doesn't require a CORS preflight request, and then try to get the same resource without the preflight OPTIONS request for the fetch and will fail due to browser restrictions.

Another way to get around this is to make sure that that the S3Image includes crossorigin: 'use-credentials' as mentioned above. In the file that you use S3Image, (I have a component that creates a cached version of the S3Image, so that is the perfect place for me), override S3Image's prototype imageEl method to force it to include this attribute.

S3Image.prototype.imageEl = function (src, theme) {
    if (!src) {
        return null;
    }
    var selected = this.props.selected;
    var containerStyle = { position: 'relative' };
    return (React.createElement("div", { style: containerStyle, onClick: this.handleClick },
        React.createElement("img", { crossOrigin: 'use-credentials', style: theme.photoImg, src: src, onLoad: this.handleOnLoad, onError: this.handleOnError}),
        React.createElement("div", { style: selected ? theme.overlaySelected : theme.overlay })));
};

403 issue is now resolved. What pain aggrr!


R
Rudolf B
<AllowedOrigin>*</AllowedOrigin>

is not a good idea because with * you grant any website access to the files in your bucket. Instead, you should specify which origin is exactly permitted to use resources from your bucket. Usually, that is your domain name like

<AllowedOrigin>https://www.example.com</AllowedOrigin>

or if you want to include all possible subdomains:

<AllowedOrigin>*.example.com</AllowedOrigin>

G
Gaurang Sondagar

Below is the configuration and it's fine to work for me. I hope it will help to resolve your issue on AWS S3.

<?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>
    <ExposeHeader>ETag</ExposeHeader>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

This worked for me to start off, then I tightened security by removing methods that weren't needed, and specifying it to only the headers I wanted
R
Renish Gotecha

In my case, I solve it with the below configuration first, go to the Permissions, Then go to the Cross-origin resource sharing (CORS) Then click on Edit and paste the below code ...

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "http://www.example1.com"
        ],
        "ExposeHeaders": []
    },
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "http://www.example2.com"
        ],
        "ExposeHeaders": []
    },
    {
        "AllowedHeaders": [],
        "AllowedMethods": [
            "GET"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]

Click here for more information


T
TigerBear

The accepted answer works, but it seems that if you go to the resource directly, then there are no cross-origin headers. If you are using cloudfront, this will cause cloudfront to cache the version without headers.When you then go to a different url that loads this resource, you will get this cross-origin issue.


A
Alexander

If your CORS settings do not help you.

Verify the configuration S3 is correct. I had an invalid bucket name in Storage.configure. I used a short name of bucket and it caused an error:

No 'Access-Control-Allow-Origin' header is present on the requested resource.


Y
Yossi Vainshtein

For what it's worth, I've had a similar issue - when trying to add a specific allowed origin (not *).

Turns out i had to correct

<AllowedOrigin>http://mydomain:3000/</AllowedOrigin>

to

<AllowedOrigin>http://mydomain:3000</AllowedOrigin>

(note the last slah in the URL)

Hope this helps someone


A
Arun K

Most of the answers above didn't work. I was trying to upload image to S3 bucket using react-s3 and I got this

Cross-Origin Request Blocked

error.

All you have to do is add CORS Config in s3 Bucket Go to S3 Bucket -> Persmission -> CORS Configuration And paste the below

<CORSConfiguration>
 <CORSRule>
   <AllowedOrigin>*</AllowedOrigin>

   <AllowedMethod>PUT</AllowedMethod>
   <AllowedMethod>POST</AllowedMethod>
   <AllowedMethod>DELETE</AllowedMethod>

   <AllowedHeader>*</AllowedHeader>
 </CORSRule>
 <CORSRule>
   <AllowedOrigin>*</AllowedOrigin>

   <AllowedMethod>PUT</AllowedMethod>
   <AllowedMethod>POST</AllowedMethod>
   <AllowedMethod>DELETE</AllowedMethod>

   <AllowedHeader>*</AllowedHeader>
 </CORSRule>
 <CORSRule>
   <AllowedOrigin>*</AllowedOrigin>
   <AllowedMethod>GET</AllowedMethod>
 </CORSRule>
</CORSConfiguration>

Replace * with your website url. Reference : AWS CORS Settings


S
Serhii Popov

I had a similar problem and coderVishal's answer helped me resolve this, but in my case, I needed to use a Terraform with the next configuration:

resource "aws_s3_bucket" "bucket" {
  bucket = var.bucket
  acl    = "public-read"

  # Cross-origin resource sharing (CORS)
  cors_rule {
    allowed_headers = ["*"]
    allowed_methods = ["GET", "HEAD"]
    allowed_origins = ["*"]
    expose_headers  = []
    max_age_seconds = 3000
  }
}

Read more about cors_rule argument in the documentation.


S
Sage

for me, not add region

const s3 = new aws.S3({ apiVersion: '2006-03-01', region: 'us-west-2' });