← Back to list

About opaque responses

CORS has always been intriguing to me. It helps us to get 3rd party data into our websites and applications, in a trustworthy way. It also…

Lucien Immink in Team Rockstars IT · 2024-06-13 10:14 · 1 claps · 2.6 min read
#http-response #javascript #cors #opaque-response #no-cors
Open on Medium ↗
Wiki topics: 🌐 · Web Development

About opaque responses

CORS has always been intriguing to me. It helps us to get 3rd party data into our websites and applications, in a trustworthy way. It also helps to keep 3rd parties from displaying our data without our explicit consent. A lot has been written about CORS so I don’t want to dive into the basics to much here. If you are interested in CORS; by all means check out this excellent article at MDN: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

I do want to spend some time to zoom-in into opaque responses, what they are, what they are for, their downsides and what to do, so let’s dive in!

Let’s start by fetching a file from the internet, not by using an img tag but by using JavaScript:

try {
  const response = await fetch(
    "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
  );
  const blob = await response.blob();
  console.log(blob);
} catch (e) {
  console.error(e);
}

this will throw an error:

Access to fetch at 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png' from origin [current site if not www.google.com]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.

This is because the origin (google.com) does not allow to us to read the contents of this resource. Content which we need to fully determine the contents of this resource. Note that the browser has a mechanism for when this resource is called directly from an img tag. Sometimes we do need to use JavaScript, for example if we want to load the image into a canvas, if we want to cache the image using a service-worker, etc.

In case of caching by using a service-worker you might be inclined to add the no-cors option to still fetch and store the resource without knowing what’s inside. Let’s go ahead and do just that

try {
  const response = await fetch(
    "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png",
    {
      mode: "no-cors",
    }
  );
  const blob = await response.blob();
  console.log({response, blob});
} catch (e) {
  console.error(e);
}

Now we do get a respone and an empty blob. A thing to note here is that the response has a statusCode of 0 while devtools network tab will show 200. Reason is that JavaScript will not be able to see the contents of the response but it can validate that a response has been returned: an opaque response. This comes in handy if you want to store the response in a cache.

What I didn’t know, but found out because I was caching 2500 images is that cached opaque responses are bigger in size compared to their cors brothers and sisters. Actually: about 7 megabyte of padding is added in chromium based browsers. 7 megabyte per resource! In my case it resulted in a ~ 18 gigabyte overhead! The padding is added to avoid leakage of cross-domain information.

In my case the server I fetched the images from was capable of CORS I just forgot to mention it. My UI is using img tags and I have a service-worker that intercepts all calls that end with .gif, .png, .webp, etc. In this case you need to add the crossorigin attribute to the img tag to inform the service-worker that this request should be treated as a cors request. Those 2500 images now take up about 80 megabyte of cache. Quite an improvement! Read more about the crossorigin attribute here: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin

Unhappy cache-size

Unhappy cache-size

Happy cache-size

Happy cache-size


메타데이터
post_id
4b441a45ea0f
slug
about-opaque-responses-4b441a45ea0f
url
https://medium.com/team-rockstars-it/about-opaque-responses-4b441a45ea0f
canonical_url
https://medium.com/team-rockstars-it/about-opaque-responses-4b441a45ea0f
author_url
https://medium.com/@lucien.immink
status
ok
fetched_at
2026-06-14 11:28:49