Access-Control-Expose-Headers
Browsers restrict which response headers JavaScript reads after a cross-origin request. The Access-Control-Expose-Headers response header lists which headers the browser is allowed to expose to JavaScript in a CORS request.
Usage
By default, only a small set of response headers is accessible to front-end JavaScript after a cross-origin request. These CORS-safelisted response headers are Cache-Control, Content-Language, Content-Length, Content-Type, Expires, Last-Modified, and Pragma.
Any other header the client needs to read must be explicitly listed in Access-Control-Expose-Headers. Without the listing, the browser hides the header value from scripts even though the network layer received the data.
This header differs from Access-Control-Allow-Headers in direction: Access-Control-Allow-Headers governs which headers a request is allowed to send, while Access-Control-Expose-Headers governs which headers a response makes readable to JavaScript.
The header belongs on the actual response, not the
preflight. A common misconfiguration lists the
exposure only in the OPTIONS preflight
answer, where the browser ignores the value, and the
symptom is always the same: the header shows in the
DevTools network panel while
response.headers.get() returns null. The network
layer received the data, and the browser withheld
the value from script because the serving response
never exposed the name. Listing custom headers like
X-Total-Count or X-Request-ID on
every cross-origin response, not the preflight,
resolves the mismatch.
Directives
Header name list
A comma-separated set of response header names the browser is permitted to expose to the calling script.
Access-Control-Expose-Headers: X-Request-ID, X-RateLimit-Remaining
* (wildcard)
The asterisk acts as a wildcard for requests without
credentials, exposing all response headers to JavaScript
except the forbidden response-header names
Set-Cookie and Set-Cookie2, which stay
hidden regardless.
Access-Control-Expose-Headers: *
Example
An API returns a custom request identifier and a rate-limit counter. Both headers are listed so the client-side code has access to read them.
Access-Control-Allow-Origin: https://app.example.re
Access-Control-Expose-Headers: X-Request-ID, X-RateLimit-Remaining
X-Request-ID: abc-123-def
X-RateLimit-Remaining: 47
A server exposing the Content-Encoding header alongside a custom header for a non-credentialed request.
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Content-Encoding, X-Trace-ID
See also
- Fetch Standard: HTTP Access-Control-Expose-Headers
- Access-Control-Allow-Headers
- Access-Control-Allow-Origin
- CORS
- HTTP headers