30

I've noticed that the results of and XMLHttpRequest.getResponseHeader() don't always match the real headers returned (if the request is made in a regular manner).

For example, assume I'm making an xhr request for https://foo.example.com/api/resource/100. In Chrome's developer console, under 'Network', I can see the response being made -- I can also see all of the response headers (say, 10). However (copy-pasted console):

> response
  XMLHttpRequest
> response.getAllResponseHeaders();
  "content-type: text/html
  " 

Are there any restrictions on what headers are available? Is this dependent on the response type? I remember getting a complete set of headers for 404s but just this one for 400s.

What gives?

2
  • If I make a request to http://stackoverflow.com/ on this page, I am able to get all headers back. I'm not sure how to reproduce.
    – pimvdb
    Sep 18, 2011 at 17:06
  • I'm aware of the vagueness -- trying to narrow down to a suitable case. The original request made is cross-origin request, with Access-Control-Allow-Origin. Excuse the rushed feeling of the question, will elaborate soon: I didn't have time to investigate this further at the moment. I was hoping this was some sort of a known restriction that I'm unaware of.
    – maligree
    Sep 18, 2011 at 17:12

2 Answers 2

37

The current state of standardizing the XMLHttpRequest API does only restrict the access to the Set-Cookie and Set-Cookie2 header fields:

client.getAllResponseHeaders()

Returns all headers from the response, with the exception of those whose field name is Set-Cookie or Set-Cookie2.

Any other header field should be returned.

But as you’re doing a cross-origin request, the browser needs to implement XMLHttpRequest Level 2 as the original XMLHttpRequest does only allow same-origin requests:

The XMLHttpRequest Level 2 specification enhances the XMLHttpRequest object with new features, such as cross-origin requests […]

There you can read that the “Cross-Origin Resource Sharing specification filters the headers that filters the headers that are exposed by getResponseHeader() for non same-origin requests.”. And that specification forbids access to any response header field other except the simple response header fields (i.e. Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, and Pragma):

User agents must filter out all response headers other than those that are a simple response header […]

E.g. the getResponseHeader() method of XMLHttpRequest will therefore not expose any header not indicated above.

4
  • 1
    Right, thanks. There are still some mysteries left, though.. I've set a proper Access-Control-Expose-Headers: -- only to find out it works only in Gecko, not WebKit. WebKit happily "Refused to get unsafe header (..)", Gecko sees no problem. Second issue: getAllResponseHeaders() lies. I can getResponseHeader() headers that the former doesn't list as available.
    – maligree
    Sep 19, 2011 at 7:16
  • @maligree: WebKit doesn’t support the Access-Control-Expose-Headers yet. But what about the other issue? What browser does that?
    – Gumbo
    Sep 19, 2011 at 17:14
  • Yes, I've stumbled upon that bugzilla issue -- but seeing the date it was opened, I took it with a grain of salt . And as to the second issue, I'm seeing this in Firefox 6. getAllResponseHeaders() returns "", while a getResponseHeader('content-length') or getResponseHeader('www-authenticate') (which is one of the headers I'm setting and Access-Control-Expose-Header'ing) returns the proper header value. I'd rather not expose the URI used at this time, but if it helps, I can devise an isolated test case later.
    – maligree
    Sep 19, 2011 at 19:56
  • @maligree you meant null right ? cf bugzilla.mozilla.org/show_bug.cgi?id=608735
    – Knu
    Jan 14, 2018 at 3:58
3

It's the Access-Control-Allow-Origin header and the way it allows to prevent which headers are exposed to the browser. Docs at mozilla.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.