Accessing the web page's HTTP Headers in JavaScript

Viewed 761864
18 Answers

It's not possible to read the current headers. You could make another request to the same URL and read its headers, but there is no guarantee that the headers are exactly equal to the current.


Use the following JavaScript code to get all the HTTP headers by performing a get request:

var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
alert(headers);

Unfortunately, there isn't an API to give you the HTTP response headers for your initial page request. That was the original question posted here. It has been repeatedly asked, too, because some people would like to get the actual response headers of the original page request without issuing another one.


For AJAX Requests:

If an HTTP request is made over AJAX, it is possible to get the response headers with the getAllResponseHeaders() method. It's part of the XMLHttpRequest API. To see how this can be applied, check out the fetchSimilarHeaders() function below. Note that this is a work-around to the problem that won't be reliable for some applications.

myXMLHttpRequest.getAllResponseHeaders();

This will not give you information about the original page request's HTTP response headers, but it could be used to make educated guesses about what those headers were. More on that is described next.


Getting header values from the Initial Page Request:

This question was first asked several years ago, asking specifically about how to get at the original HTTP response headers for the current page (i.e. the same page inside of which the javascript was running). This is quite a different question than simply getting the response headers for any HTTP request. For the initial page request, the headers aren't readily available to javascript. Whether the header values you need will be reliably and sufficiently consistent if you request the same page again via AJAX will depend on your particular application.

The following are a few suggestions for getting around that problem.


1. Requests on Resources which are largely static

If the response is largely static and the headers are not expected to change much between requests, you could make an AJAX request for the same page you're currently on and assume that they're they are the same values which were part of the page's HTTP response. This could allow you to access the headers you need using the nice XMLHttpRequest API described above.

function fetchSimilarHeaders (callback) {
    var request = new XMLHttpRequest();
    request.onreadystatechange = function () {
        if (request.readyState === XMLHttpRequest.DONE) {
            //
            // The following headers may often be similar
            // to those of the original page request...
            //
            if (callback && typeof callback === 'function') {
                callback(request.getAllResponseHeaders());
            }
        }
    };

    //
    // Re-request the same page (document.location)
    // We hope to get the same or similar response headers to those which 
    // came with the current page, but we have no guarantee.
    // Since we are only after the headers, a HEAD request may be sufficient.
    //
    request.open('HEAD', document.location, true);
    request.send(null);
}

This approach will be problematic if you truly have to rely on the values being consistent between requests, since you can't fully guarantee that they are the same. It's going to depend on your specific application and whether you know that the value you need is something that won't be changing from one request to the next.


2. Make Inferences

There are some BOM properties (Browser Object Model) which the browser determines by looking at the headers. Some of these properties reflect HTTP headers directly (e.g. navigator.userAgent is set to the value of the HTTP User-Agent header field). By sniffing around the available properties you might be able to find what you need, or some clues to indicate what the HTTP response contained.


3. Stash them

If you control the server side, you can access any header you like as you construct the full response. Values could be passed to the client with the page, stashed in some markup or perhaps in an inlined JSON structure. If you wanted to have every HTTP request header available to your javascript, you could iterate through them on the server and send them back as hidden values in the markup. It's probably not ideal to send header values this way, but you could certainly do it for the specific value you need. This solution is arguably inefficient, too, but it would do the job if you needed it.

Using XmlHttpRequest you can pull up the current page and then examine the http headers of the response.

Best case is to just do a HEAD request and then examine the headers.

For some examples of doing this have a look at http://www.jibbering.com/2002/4/httprequest.html

Just my 2 cents.

(2021) An answer without additional HTTP call

While it's not possible in general to read arbitrary HTTP response headers of the top-level HTML navigation, if you control the server (or middleboxes on the way) and want to expose some info to JavaScript that can't be exposed easily in any other way than via a header:

You may use Server-Timing header to expose arbitrary key-value data, and it will be readable by JavaScript.

(*in supported browsers: Firefox 61, Chrome 65, Edge 79; no Safari yet and no immediate plans for shipping as of 2021.09; no IE)

Example:

server-timing: key;desc="value"
server-timing: key1;desc="value1"
server-timing: key2;desc="value2"
  • or use its compact version where you expose multiple pieces of data in one header, comma-separated.
server-timing: key1;desc="value1", key2;desc="value2"

Example of how Wikipedia uses this header to expose info about cache hit/miss:

Usage of server-timing response header on Wikipedia

Code example (need to account for lack of browser support in Safari and IE):

if (window.performance && performance.getEntriesByType) { // avoid error in Safari 10, IE9- and other old browsers
    let navTiming = performance.getEntriesByType('navigation')
    if (navTiming.length > 0) { // still not supported as of Safari 14...
        let serverTiming = navTiming[0].serverTiming
        if (serverTiming && serverTiming.length > 0) {
            for (let i=0; i<serverTiming.length; i++) {
                console.log(`${serverTiming[i].name} = ${serverTiming[i].description}`)
            }
        }
    }
}

This logs cache = hit-front in supported browsers.

Notes:

  • as mentioned on MDN, the API is only supported over HTTPS
  • if your JS is served from another domain, you have to add Timing-Allow-Origin response header to make the data readable to JS (Timing-Allow-Origin: * or Timing-Allow-Origin: https://www.example.com)
  • Server-Timing headers support also dur(header) field, readable as duration on JS side, but it's optional and defaults to 0 in JS if not passed
  • regarding Safari support: see bug 1 and bug 2 and bug 3
  • You can read more on server-timing in this blog post
  • Note that performance entries buffers might get cleaned by JS on the page (via an API call), or by the browser, if the page issues too many calls for subresources. For that reason, you should capture the data as soon as possible, and/or use PerformanceObserver API instead. See the blog post for details.

Another way to send header information to JavaScript would be through cookies. The server can extract whatever data it needs from the request headers and send them back inside a Set-Cookie response header — and cookies can be read in JavaScript. As keparo says, though, it's best to do this for just one or two headers, rather than for all of them.

Allain Lalonde's link made my day. Just adding some simple working html code here.
Works with any reasonable browser since ages plus IE9+ and Presto-Opera 12.

<!DOCTYPE html>
<title>(XHR) Show all response headers</title>

<h1>All Response Headers with XHR</h1>
<script>
 var X= new XMLHttpRequest();
 X.open("HEAD", location);
 X.send();
 X.onload= function() { 
   document.body.appendChild(document.createElement("pre")).textContent= X.getAllResponseHeaders();
 }
</script>

Note: You get headers of a second request, the result may differ from the initial request.


Another way
is the more modern fetch() API
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
Per caniuse.com it's supported by Firefox 40, Chrome 42, Edge 14, Safari 11
Working example code:

<!DOCTYPE html>
<title>fetch() all Response Headers</title>

<h1>All Response Headers with fetch()</h1>
<script>
 var x= "";
 if(window.fetch)
    fetch(location, {method:'HEAD'})
    .then(function(r) {
       r.headers.forEach(
          function(Value, Header) { x= x + Header + "\n" + Value + "\n\n"; }
       );
    })
    .then(function() {
       document.body.appendChild(document.createElement("pre")).textContent= x;
    });
 else
   document.write("This does not work in your browser - no support for fetch API");
</script>

If we're talking about Request headers, you can create your own headers when doing XmlHttpRequests.

var request = new XMLHttpRequest();
request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
request.open("GET", path, true);
request.send(null);

To get the headers as an object which is handier (improvement of Raja's answer):

var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
headers = headers.split(/\n|\r|\r\n/g).reduce(function(a, b) {
    if (b.length) {
        var [ key, value ] = b.split(': ');
        a[key] = value;
    }
    return a;
}, {});

Using mootools, you can use this.xhr.getAllResponseHeaders()

I think the question went in the wrong way, If you want to take the Request header from JQuery/JavaScript the answer is simply No. The other solutions is create a aspx page or jsp page then we can easily access the request header. Take all the request in aspx page and put into a session/cookies then you can access the cookies in JavaScript page..

Related