3

I'm setting up my legacy site as a PWA. It is a PHP site. All my site assets sit on a CDN and I use versioning tags appended to the paths to each. I'd like to use a cache first strategy on them. To do that I have to add crossorigin="anonymous" to all my assets to get a cors response instead of an opaque one. Inline images, css, js files are easy, but is there a way to get images referenced in CSS to return cors? Currently they all come back as opaque.

enter image description here

Workbox's site that reference setting this up...

https://developers.google.com/web/tools/workbox/guides/handle-third-party-requests

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Adam Youngers
  • 6,421
  • 7
  • 38
  • 50

1 Answers1

2

While you can't use a no-cors (opaque) response when the browser expects a cors response, the reverse is generally okay. This means that you should be able to intercept the outgoing no-cors request in your service worker, rewrite it so that it's a cors request, and then both cache that cors response, and pass it on to the page to use.

You could accomplish this with a custom route that matched your no-cors .svg requests and implemented a CacheFirst strategy with a custom requestWillFetch plugin that rewrote the request.

I haven't tested this myself, but I think the following would work:

import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';

function requestWillFetch({request}) {
  return new Request(request, {mode: 'cors'});
}

registerRoute(
  ({request, url}) => request.mode === 'no-cors' &&
                      url.pathname.endsWith('.svg'),
  new CacheFirst({
    plugins: [{requestWillFetch}],
  })
);

You can use the generateSW mode of the Workbox build tools to create this route for you with the following configuration:

{
  // ...your other top-level options here...
  runtimeCaching: [{
    urlPattern: ({request, url}) => request.mode === 'no-cors' &&
                                    url.pathname.endsWith('.svg'),
    handler: 'CacheFirst',
    options: {
      plugins: [{
        requestWillFetch: ({request}) => new Request(request, {mode: 'cors'}),
      }],
    },
  }, {
    // ...your other runtime caching entries here...
  }],
};
Jeff Posnick
  • 53,580
  • 14
  • 141
  • 167