Angular Service Worker CORS Error

I have an Angular 9 app that displays images from S3 with Cloudflare caching = standard… The app works great until I try to cache these images using Angular’s Service Worker. The Service Worker is triggering CORS errors “I think” because no Origin is sent in the request header. The Service Worker has no configuration options that I can find. Is it possible to configure Cloudflare to serve these images and ignore CORS in this case?

I can rename an S3 image and NOT get a CORS error for the new image. So I thought this was a Cloudflare caching CORS headers problem as described here: https://support.cloudflare.com/hc/en-us/articles/200308847-Using-cross-origin-resource-sharing-CORS-with-Cloudflare. However, ~1 hour later the new renamed images were also showing CORS errors. I can’t make any sense of this behavior. I can also add a random query string to an image and NOT get a CORS error but I suspect they would start to error over time too. Updating the last modified date on the file and doing a Cloudflare full purge made no difference.

Setting Cloudflare caching = development mode made no difference.

I have a detailed write-up on stackoverflow here:

Thanks!

CORS Error Message:
Access to fetch at ‘https://assets.myurl.net/images/banner.jpg’ from origin ‘https://localhost:8100’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

Hi there!

Sorry to hear about your CORS error you are seeing. This looks to be a product of the testing/development process you are using.

the myurl.net domain in this case will need to send the correct CORS headers to allow for scripts to be run from your dev machine – localhost + the port.

I hope this helps!

1 Like

Thanks Peter! I’m not 100% clear on your reply but this is a production issue that I was able to replicate on my local PC for troubleshooting (hence the localhost urls you’re seeing). The assets.myurl.net S3 bucket has the following CORs config so should allow any request (including from localhost) to get an image. Are you saying that this S3 CORs script needs to be modified and is somehow blocking localhost?

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

HI there,

Your CORS configuration here looks like it might actually be okay – though it still sounds like your Origin server is not returning the correct CORS headers in the HTTP response.

When you use your browser’s developer tools – do you see these Access-Control-Allow-Origin: * headers being returned in the HTTP response from your S3 bucket?

1 Like

Thanks Peter! I re-visited request/response headers coming from the Angular Service Worker and did some additional testing.

I made some S3 CORS changes (and then reverted them). Switched Cloudflare development mode on (and then off again). Purged everything in Cloudflare a few times. I did all these things yesterday without success.

So all today’s changes were ultimately reverted but now I see CORS headers in the Service Worker response:
accept-ranges: bytes
access-control-allow-methods: GET, HEAD
access-control-allow-origin: *

And I can no longer reproduce the CORS errors and I can’t explain why this is now working. I’ve been testing different scenarios in production for ~30 mins and only once did I see CORS errors in the Chrome console (but images always displayed correctly).

I still don’t see an origin header the Service Worker request so in theory S3 shouldn’t return access-control-allow-origin in the response – but it does. I also see the images in the application cache (so caching is confirmed on).

I’m going to do some additional testing on different PCs and browsers and check back if I manage to reproduce the problem again.

Okay sure thing – definitely keep me posted about your testing!

One thing I wanted to circle back to briefly was in your original post:

Is it possible to configure Cloudflare to serve these images and ignore CORS in this case?

So one additional thing I wanted to mention is that Cloudflare can actually be used to append CORS headers using Workers by modifying the Response headers during the Request/Response life-cycle. But that being said, it is actually your Browser that is blocking the behavior.

The CORS headers act as a “permissions list” of sorts that tell your browser the scripts (or other resources) that can execute when the page loads. This might be an oversimplification but it’s a safety guard for your browser to prevent the browser from executing a malicious script supplied by an external host.

Anyway, please do let us know if that issue crops up again and in the meantime I hope this helps!

Thanks Peter! This issue appears to be resolved on all browsers EXCEPT Safari. Testing on a macbookpro, Safari does NOT return a access-control-allow-origin header in the response but Chrome does. The request header is the same in both browsers.

Cloudflare workers are very interesting. Will dig deeper into that.

1 Like

I am glad to hear that the headers look like they are returning on (at least) most of the Browsers you are testing… it does sound strange that Safari would be a hold-out… I am not really sure what to make of it to be honest, but I suppose my mind goes to ensuring that the browser cache is all cleared out. Any chance you might be able to double check this? It shouldn’t really make a difference, but it is worth checking I suppose.

I am glad you like the Workers product – It’s definitely one of my favorites – and it can sometimes act as a solution when you need to transform the Request or Response without needing to change anything on your origin server and might work for your use-case.

That being said, do let me know if the browser cache clearing doesn’t work!

1 Like

Thanks Peter! Yes - we’ve confirmed Safari as having this cors problem – across multiple PCs, devices, and networks. There are recent posts about Safari only CORS issues but I haven’t found a solution/work-around to this specific issue. https://developer.apple.com/forums/thread/85197

Cloudflare Workers sounds like the only solution (for now). Maybe something like always return CORS headers for image requests.

I had the same problem, and here is what I did to solve the problem:

Go to your S3 bucket. Click on Permissions, then CORS configuration. Change the allowed origin from this:

<AllowedOrigin>*</AllowedOrigin>

TO

<AllowedOrigin>http://*</AllowedOrigin>
<AllowedOrigin>https://*</AllowedOrigin>
<AllowedOrigin>https://www.yourdomain.com</AllowedOrigin>

The browsers that have problems normally have cache disabled by default. For example, incognito mode is more prone to have this kind of issues.

Here is an example of an entire CORS that should work for you.

<CORSConfiguration>
<CORSRule>
    <AllowedOrigin>http://*</AllowedOrigin>
    <AllowedOrigin>https://*</AllowedOrigin>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>