I was looking for the specific security reasons as to why this was added. It was kind of a WTH moment when I was implementing cors and could see all the headers being returned but I couldn't access them via javascript..
3 Answers
CORS is implemented in such a way that it does not break assumptions made in the pre-CORS, same-origin-only world.
In the pre-CORS world, a client could trigger a cross-origin request (for example, via a script tag), but it could not read the response headers.
In order to ensure that CORS doesn't break this assumption, the CORS spec requires the server to give explicit permissions for the client to read those headers (via the Access-Control-Expose-Headers
header). This way, unauthorized CORS requests behave as they did in a pre-CORS world.

- 42,091
- 47
- 181
- 266

- 45,581
- 16
- 101
- 95
-
2I find this link is a good example for this answer : https://fetch.spec.whatwg.org/#example-cors-with-response-header – yusong Nov 21 '19 at 00:40
-
6In other words, `Access-Control-Expose-Headers` isn't for security at all, but for compatibility? There is no attack that we use `Access-Control-Expose-Headers` to mitigate? – DavidS Dec 07 '20 at 17:48
-
I see `Access-Control-Expose-Headers` is returned only for the first request, the continued requests with the same CORS origin are not getting it again. Do you help me to know why? – Kanagavelu Sugumar Feb 21 '23 at 09:36
Here is the reason why Access-Control-Expose-Headers is needed :
Access-Control-Expose-Headers (optional) - The XMLHttpRequest 2 object has a getResponseHeader() method that returns the value of a particular response header. During a CORS request, the getResponseHeader() method can only access simple response headers. Simple response headers are defined as follows:
- Cache-Control
- Content-Language
- Content-Type
- Expires
- Last-Modified
- Pragma
If you want clients to be able to access other headers, you have to use the Access-Control-Expose-Headers header. The value of this header is a comma-delimited list of response headers you want to expose to the client.
for more reference please dig into the link https://www.html5rocks.com/en/tutorials/cors/
Happy coding !!

- 2,931
- 4
- 28
- 34
-
Also `Content-Length`, see https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_response_header. – diachedelic Sep 24 '22 at 00:30
This is a pretty good question. Looking through http://www.w3.org/TR/cors/#simple-response-header, it's not obvious why you would want to or need to do this.
The CORS spec puts a lot of weight into the idea that you have to have a pre-request handshake where the client asks for a type of connection and the server responds that it'll allow it - so this may just be another aspect of that.
By default content-length isn't a permitted header so I ran into the same issue (later on when I needed to access WebDAV and had to modify the allowable params).. CORS really doesn't make a lot of sense (to me) in the first place so it wouldn't surprise me if swaths of it that are capricious.

- 27,321
- 5
- 74
- 91
-
4CORS feels capricious precisely because the spec authors have taken care to think hard about it. CORS must enable cross-origin requests while still protecting the browser's same-origin policy. It is the need to balance these two (sometimes opposing) forces that makes the CORS spec difficult to understand. – monsur Sep 04 '14 at 19:29
-
1The link to the recommendation is the most helpful pointer I've gotten this month and more. I knew about Access-Control-Allow-Headers but hadn't considered Access-Control-Expose-Headers and couldn't understand why my "Links" headers weren't getting to my Backbone Collection. Astounding. – mcdave Nov 25 '15 at 02:50