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

Last updated: September 21, 2026