Chrome Dev Summit is back! Visit to secure your spot in workshops, office hours and learning lounges!

Handle Third Party Requests

A lot of websites will use files from a different origin. For example, if you use Google Fonts, you’ll be importing the styles and fonts from Any request for a file from a different origin is known as a cross-origin request and these requests require special handling in Workbox.

In this guide we are going to look at how a cross-origin request can be different and what you can do in Workbox to support these requests.

Cross-Origin Requests and Opaque Responses

One of the security mechanisms in browsers is that when a piece of JavaScript requests a URL from a different origin, it’s prevented from being able to access the body and many other details of the response.

When you get a response like this, it’s known as an "opaque response". Some requests can be read in JavaScript if the server returns CORS headers, but a number of sites will not do this.

In service workers, you can make requests to third-parties and cache the responses. For opaque responses, the contents of the Response will still be hidden. You can’t even check the status code of the response. Because of this, Workbox treats opaque responses differently.

You can learn more about opaque responses from this Stack Overflow Q&A.

Remember to Opt-in to CORS Mode

If you're loading assets from a third party web server that does support CORS, but you're unexpectedly getting back opaque responses, it could be due to how your web app makes those cross-origin requests.

For example, the following HTML will trigger no-cors requests that lead to opaque responses, even if the server supports CORS:

<link rel="stylesheet" href="">
<img src="">

In order to explicitly trigger a cors request, and get back a non-opaque response, you need to explicitly opt-in to CORS mode by adding the crossorigin attribute to your HTML:

<link crossorigin="anonymous" rel="stylesheet" href="">
<img crossorigin="anonymous" src="">

Workbox Caches Opaque Response Sometimes

In general, Workbox will not cache opaque responses.

The reason for this is that it’s very easy to get into a bad state.

Let’s say a developer set up a route with a CacheFirst strategy.

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

  new CacheFirst(),

This response would cache the opaque response and serve it up from that point onwards. The problem is that if that request fails for any reason, Workbox won’t be able to detect this and will continue to serve up the broken response. The user will be in a broken state.

However, it’s not a bad thing to want to try and add some fault tolerance to these requests so Workbox will allow opaque responses to be cached with the NetworkFirst and StaleWhileRevalidate strategies. Since these strategies regularly update the cached response, it’s much safer to cache them as hopefully a bad request will be short lived and used rarely.

import {registerRoute} from 'workbox-routing';
import {NetworkFirst, StaleWhileRevalidate} from 'workbox-strategies';

  new NetworkFirst(),

// OR

  new StaleWhileRevalidate(),

If you use another caching strategy and an opaque response is returned, Workbox will log a warning letting you know that the response wasn’t cached.

Example warning when an opaque response isn't cached.

Force Caching of Opaque Responses

If you are certain that you want to cache an opaque response, you can configure that behavior using a plugin. This example uses workbox-cacheable-response:

import {registerRoute} from 'workbox-routing';
import {NetworkFirst, StaleWhileRevalidate} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';

  new CacheFirst({
    plugins: [
      new CacheableResponsePlugin({
        statuses: [0, 200]

Learn more about using plugins