50

I have a $.ajax request on the same domain and I want to read the cookie. It keeps returning null.

$.ajax({
    type: 'GET',
    url: myUrl,
    success: function(output, status, xhr) {
        alert(xhr.getResponseHeader("MyCookie"));
    },
    cache: false
});

Any ideas? I'm using Chrome for this.

Kees C. Bakker
  • 32,294
  • 27
  • 115
  • 203

4 Answers4

54

The browser cannot give access to 3rd party cookies like those received from ajax requests for security reasons, however it takes care of those automatically for you!

For this to work you need to:

1) login with the ajax request from which you expect cookies to be returned:

$.ajax("https://example.com/v2/login", {
     method: 'POST',
     data: {login_id: user, password: password},
     crossDomain: true,
     success: login_success,
     error: login_error
  });

2) Connect with xhrFields: { withCredentials: true } in the next ajax request(s) to use the credentials saved by the browser

$.ajax("https://example.com/v2/whatever", {
     method: 'GET',
     xhrFields: { withCredentials: true },
     crossDomain: true,
     success: whatever_success,
     error: whatever_error
  });

The browser takes care of these cookies for you even though they are not readable from the headers nor the document.cookie

MrE
  • 19,584
  • 12
  • 87
  • 105
  • 1
    I have an sso server. I have two sso client apps. In app1 I login and it returns a cookie that is set for the sso server domain in my browser. Now on subsequent ajax requests to sso server both the client apps attach this cookie successfully. In app2 though the cookie returned from the ajax response is not set in the browser and it is not attached on subsequent calls to sso server. Quite strange, can you please give some helpful hint? – muasif80 Mar 19 '17 at 13:59
  • 2
    I was not using this xhrFields: { withCredentials: true }, crossDomain: true, on the first ajax call. Its needed on first ajax call too to set the cookie in browser successfully. Once I did that, it worked successfully. – muasif80 Mar 19 '17 at 14:12
  • 1
    +10 This was super useful for building out a bot to monitor and automate a third party vendor site! – Michael Hobbs May 28 '17 at 11:44
49

You're looking for a response header of Set-Cookie:

xhr.getResponseHeader('Set-Cookie');

It won't work with HTTPOnly cookies though.

Update

According to the XMLHttpRequest Level 1 and XMLHttpRequest Level 2, this particular response headers falls under the "forbidden" response headers that you can obtain using getResponseHeader(), so the only reason why this could work is basically a "naughty" browser.

Community
  • 1
  • 1
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
3
xhr.getResponseHeader('Set-Cookie');

It won't work for me.

I use this

function getCookie(cname) {
    var name = cname + "=";
    var ca = document.cookie.split(';');
    for(var i=0; i<ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1);
        if (c.indexOf(name) != -1) return c.substring(name.length,c.length);
    }
    return "";
} 

success: function(output, status, xhr) {
    alert(getCookie("MyCookie"));
},

http://www.w3schools.com/js/js_cookies.asp

alexis
  • 569
  • 5
  • 12
  • I wonder who ever got in mind to downvote this answer. header 'Set-Cookie' may be absent in lots of cases; document.cookie is the safe way to go. – Marco Faustinelli Nov 21 '14 at 09:17
  • 21
    document.cookie is available on the document, not the XMLHttpRequest response. – Christopher Weiss Mar 04 '15 at 21:54
  • 2
    this doedn't work: the type of cookie we are talking about are not available through code directly. you need to use xhrFields: {withCredentials: true} to request the browser to pass them back on for you. – MrE Mar 19 '17 at 14:30
0

Similar to yebmouxing I could not the

 xhr.getResponseHeader('Set-Cookie');

method to work. It would only return null even if I had set HTTPOnly to false on my server.

I too wrote a simple js helper function to grab the cookies from the document. This function is very basic and only works if you know the additional info (lifespan, domain, path, etc. etc.) to add yourself:

function getCookie(cookieName){
  var cookieArray = document.cookie.split(';');
  for(var i=0; i<cookieArray.length; i++){
    var cookie = cookieArray[i];
    while (cookie.charAt(0)==' '){
      cookie = cookie.substring(1);
    }
    cookieHalves = cookie.split('=');
    if(cookieHalves[0]== cookieName){
      return cookieHalves[1];
    }
  }
  return "";
}
cpoole
  • 346
  • 3
  • 5