Search code examples
amazon-web-servicesservice-workeramazon-cloudfront

Service Workers, AWS CloudFront and Access-Control-Allow-Origin


I'm used to building websites on my own server, adding Service Worker code to help make sure it loads even when no internet access is available and spreading the load across Amazon's CloudFront servers. But I always fetched files in my Service Worker code from my server directly. Recently I tried resolving these resources using my CloudFront URI and everything failed with the 'Access-Control-Allow-Origin' error.

I've been doing a tone of reading on this but I'm getting lost in all the details. I tried adding an XML statement to my S3 bucket under 'Permissions' and the 'CORS configuration editor' but it only partially works meaning, it only pulls down some of the files and I'm afraid I'm doing something very insecure here.

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

I also tried

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

but either the change is delayed within the system or it simply made no difference so I'm kind of at a loss as to what to look at next. Here is my Service Worker code in case that helps.

const cacheName='v2020.03.19-01';

var cacheFiles=[
    'https://xyzzy.cloudfront.net/ccmsusr/_css/animate.min.css',
    'https://xyzzy.cloudfront.net/ccmsusr/_js/jquery-3.4.1.min.js',
    'https://xyzzy.cloudfront.net/ccmsusr/_js/jquery-validate-1.19.0.min.js',
    'https://xyzzy.cloudfront.net/ccmsusr/_js/jquery-validate-additional-methods-1.19.0.min.js',
    'https://xyzzy.cloudfront.net/ccmstpl/_css/owl.carousel-2.3.4.min.css',
    'https://xyzzy.cloudfront.net/ccmstpl/_js/owl.carousel.min.js',
    'https://xyzzy.cloudfront.net/ccmstpl/_js/jquery.mobile.custom.min.js',
    'https://xyzzy.cloudfront.net/ccmstpl/_js/modernizr-3.6.0-custom-min.js',
    '/en/_css/style-ltr.css',
    '/en/_js/main.js'
]

self.addEventListener('install',e=>{
    e.waitUntil(
        caches.open(cacheName).then(cache=>{
            return cache.addAll(cacheFiles);
        })
    );
});

self.addEventListener('activate',e=>{
    e.waitUntil(
        caches.keys().then(keyList=>{
            return Promise.all(keyList.map(key=>{
                if(key!==cacheName) {
                    return caches.delete(key);
                }
            }));
        })
    );
});

// Check the cache first, if that fails look on the network. (Best for mostly static websites.)
self.addEventListener('fetch',e=>{
    e.respondWith(
        caches.match(e.request).then(response=>{
            if(response) {
                return response;
            }
            return fetch(e.request);
        })
    );
});

Anyone have any ideas on how I can get rid of this error?


Solution

  • I managed to figure this out by reading a million other posts and trying everything, in the end, this was the exact way I resolved my problem.

    In order to get the listed resources to load properly once moved to Amazon's CloudFront servers you need to add this to your S3 bucket, under Permissions/CORS configuration:

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

    Then you need to select the appropriate distribution under CloudFront and click the Behaviors tab. Create or Edit an existing Behavior and select the following settings:

    Allowed HTTP Methods: GET, HEAD, OPTIONS

    Cache Based on Selected Request Headers: Whitelist

    Add these to the right box under Whitelist Headers:

    • Access-Control-Request-Headers
    • Access-Control-Request-Method
    • Origin

    Then click the 'Yes, Edit' button at the bottom and give it about 10 minutes to propagate through the system and test using Chrome.