2

I need to get retrieve some publicly accessible files from S3.

That's my S3 CORS configuration:

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

And here's my JS code:

const response = await fetch(url, {
    mode: 'cors',
});

const blob = await response.blob();

It works, but not always. Sometimes I have the following error in the console:

Access to XMLHttpRequest at 'https://my-bycketuel/file.jpg' from origin 'https://my.host' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

But after I reload the page (sometimes several times, sometimes just once) then the error is gone and I'm able to read the response object.

wube
  • 923
  • 2
  • 10
  • 22
  • You need to whitelist {https://my-bycketuel / *} on {https://my.host/}. And that way issue would be resolved for you forever. It is cross platform access issue. Should be easy. – Kunal Vohra Mar 14 '19 at 09:12
  • Another recommended way is you can use reverse proxy to resolve issue. – Kunal Vohra Mar 14 '19 at 09:15

2 Answers2

12

OP here.

I was looking at successful and unsuccessful requests in Chrome dev tools. I found that unsuccessful requests have Status code of: 200 OK (from disk cache) when successful requests have Status code of: 200 OK

When I disable caching using cache: 'no-cache' then the problem is gone.

const response = await fetch(url, {
    method: 'GET',
    mode: 'cors',
    cache: 'no-cache',
    headers: {
        Origin: window.location.origin,
    },
});

I still don't understand why would cached request suffer from CORS issues, but at least I found a solution - or rather a workaround.


// EDIT:

I found I'm not alone: Cached non CORS response conflicts with new CORS request

wube
  • 923
  • 2
  • 10
  • 22
  • 1
    This is a bug in S3's CORS implementation. S3 fails to set `Vary: Origin` on responses to non-CORS requests, even when the bucket has CORS enabled... so Chrome assumes it can reuse the cached response in a CORS context, only to discover too late that it isn't going to work, because the cached response lacks `Access-Control-Allow-Origin` ... https://serverfault.com/a/856948/153161 – Michael - sqlbot Mar 14 '19 at 13:11
  • Life saver. I looked all over the internets for many hours to find this bit of wisdom. Thanks! – Justin Vincent May 29 '23 at 22:59
1

It seems that you are missing the

<AllowedMethod>Head</AllowedMethod>

on your config file.

I expect that is the reason you are having issues.

Make sure on Allowed Http Methods you chose Get,Head,Options as well include the Access-Control-Allow-Methods, Access-Control-Allow-Origin and Origin on your white list

Try that!

Good Luck

Jean Rauwers
  • 65
  • 1
  • 7
  • 1
    I've added the `HEAD`, but the problem is not gone. But that's most weird to me is the fact that sometimes it works, sometimes it doesn't and I can't find any reason or rule behind it. – wube Mar 14 '19 at 11:35
  • Have you checked your white list ? – Jean Rauwers Mar 14 '19 at 12:03
  • What whitelist do you mean? I already found what causes an issue. It's somehow related to caching: https://stackoverflow.com/questions/55158189/cross-origin-requests-ajax-requests-to-aws-s3-sometimes-result-in-cors-error#answer-55163299 – wube Mar 14 '19 at 13:06