1

In JavaScript, the Fetch API's access to certain headers is restricted for security reasons during a CORS request.

We can see the actual headers of a resource using curl in the terminal:

curl -I https://i.imgur.com/z4d4kWk.jpg

And here's the result:

HTTP/1.1 200 OK
Last-Modified: Thu, 02 Feb 2017 11:15:53 GMT
ETag: "18c50e1bbe972bdf9c7d9b8f6f019959"
x-amz-storage-class: STANDARD_IA
Content-Type: image/jpeg
cache-control: public, max-age=31536000
Content-Length: 146515
Accept-Ranges: bytes
Date: Sat, 14 Jul 2018 01:34:10 GMT
Age: 446795
Connection: keep-alive
X-Served-By: cache-iad2134-IAD, cache-syd18935-SYD
X-Cache: HIT, HIT
X-Cache-Hits: 1, 1
X-Timer: S1531532051.675972,VS0,VE2
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Origin: *
Server: cat factory 1.0

Here's the equivalent request using fetch:

await fetch("https://i.imgur.com/z4d4kWk.jpg", { method: 'HEAD' }).then(r => [...r.headers.entries()].map(l => l.join(": ")).join("\n"))

And here's the result:

cache-control: public, max-age=31536000
content-type: image/jpeg
last-modified: Thu, 02 Feb 2017 11:15:53 GMT

But imgur allows other origins to access that resource (see Access-Control-Allow-Origin: * in curl output above), and so we can actually get the contents of the file:

await fetch("https://i.imgur.com/z4d4kWk.jpg").then(r => r.arrayBuffer())

CORS response

So we can get the actual contents of the file, and yet we can't get the headers?

At first I thought it was because we were making a HEAD request and imgur specifies Access-Control-Allow-Methods: GET, OPTIONS, but I tried using a GET request and still got the same limited set of headers:

await fetch("https://i.imgur.com/z4d4kWk.jpg").then(r => [...r.headers.entries()].map(l => l.join(": ")).join("\n"))

Any idea why we're unable to see the headers even when we have full access to the content itself?

  • 2
    Access to the header has to be specifically enabled by the server by setting the [`Access-Control-Allow-Headers` header.](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers) –  Jul 14 '18 at 02:25
  • 1
    Wrong header! My bad. The correct one is the [`Access-Control-Expose-Headers` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers). The first one goes the *other* way, defining what the client can send in a *request*, not receive in the response. –  Jul 14 '18 at 02:34
  • 1
    This header is not generally useful to applications. If the data is compressed, it will be the compressed length. If chunked encoding is used, it will not be provided at all. – Barmar Jul 14 '18 at 05:06
  • Thanks for your replies! So it's just a consistency thing then. I guess it does sort of make sense to hide `Content-Length` even when the content can be downloaded, because the content could be infinite (dynamically generated) - or just very large, and perhaps there's some situation where the server doesn't want clients to be able to determine how big it is ahead of time. –  Jul 14 '18 at 09:45

0 Answers0