Recently I discovered a new CORS header, Access-Control-Expose-Header, which I hadn’t know about previously. As I had to do a lot of digging to get any information about it, I thought I’d make a note.
The context was that we were making a cross-domain HEAD request to establish the Content-Length of a download before performing the AJAX request.
>>> xhr.getResponseHeader("content-length"); null
It turns out that only 6 “simple” headers are allowed to be returned (for security reasons) on CORS requests. As listed in the spec, they are:
Obviously Content-Length is not one of these. In order to allow it to be read, you must specify the content-length header with the Access-Control-Expose-Headers response header. The value is a comma-separated list of headers, but as we only have one we want to expose, the response header needs to look like this:
Note that the content-length section after the colon is case insensitive, as per the HTTP Headers specification.
If you are using Jetty 8 (after Jetty 8.1.12) you can use the following syntax in your CrossOriginFilter in your web.xml to set this up:
<init-param> <param-name>exposedHeaders</param-name> <param-value>content-length</param-value> </init-param>
So there’s another thing to learn about CORS – but once you have it working, it is extremely effective.