如何从 AJAX 响应中获取 cookie?

50

我在同一域上进行$.ajax请求,想要读取cookie。但它一直返回null

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

有什么想法吗?我正在使用Chrome。

4个回答

55

出于安全原因,浏览器无法访问第三方cookie,例如从ajax请求中收到的cookie,但是它会自动为您处理这些cookie!

为了使其工作,您需要执行以下操作:

1)使用您期望返回cookie的ajax请求进行登录:

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

2) 在下一个Ajax请求中使用xhrFields: { withCredentials: true }连接来使用浏览器保存的凭据

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

尽管这些cookie无法从headersdocument.cookie读取,但浏览器会为您管理它们。


1
我有一个SSO服务器。我有两个SSO客户端应用程序。在app1中,我登录并返回一个cookie,该cookie设置为我的浏览器中SSO服务器域。现在,在后续的ajax请求到SSO服务器时,两个客户端应用程序都成功附加了此cookie。但是,在app2中,从ajax响应返回的cookie未在浏览器中设置,并且在后续调用SSO服务器时未附加。非常奇怪,请给一些有用的提示? - muasif80
2
我在第一个ajax调用中没有使用这个xhrFields: { withCredentials: true }, crossDomain: true。但是在第一个ajax调用中也需要它来成功地在浏览器中设置cookie。一旦我这样做了,它就成功地工作了。 - muasif80
1
这对于构建监控和自动化第三方供应商网站的机器人非常有用! +10 - Michael Hobbs

49

您正在寻找响应头 Set-Cookie

xhr.getResponseHeader('Set-Cookie');

然而,它在使用HTTPOnly cookie时无法工作。

更新

根据XMLHttpRequest Level 1XMLHttpRequest Level 2,这个特定的响应头属于被禁止获取的响应头之一,您可以使用getResponseHeader()来获取,所以唯一能够使其工作的原因就是“顽皮”的浏览器。


1
有没有一种方法可以指示我的浏览器将新的cookie附加到我的表单中? - Kees C. Bakker
9
我得到了空的cookie。但是在浏览器控制台中,我可以看到我进行ajax请求的文件的响应头和cookie字符串。有什么想法? :/ - trainoasis
2
我说:“拒绝获取不安全的头部' Set-Cookie'”。 - trainoasis
4
这并不是HTTPOnly的限制。XHR有一个禁止使用的标题列表,其中包括响应标题Set-Cookie。这是该列表的链接:https://fetch.spec.whatwg.org/#forbidden-header-name - Kostas Filios
禁止使用的响应头列表可在https://fetch.spec.whatwg.org/#forbidden-response-header-name找到。 - undefined
显示剩余4条评论

3
xhr.getResponseHeader('Set-Cookie');

对我来说这不起作用。

我使用这个

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


我想知道是谁想要踩这个答案。在许多情况下,头部的 'Set-Cookie' 可能不存在;使用 document.cookie 是安全的方法。 - Marco Faustinelli
21
document.cookie 可在文档中使用,而非 XMLHttpRequest 响应中。 - Christopher Weiss
2
这个不起作用:我们所讨论的 cookie 类型不能直接通过代码获取。你需要使用 xhrFields: {withCredentials: true} 来请求浏览器将它们传回给你。 - MrE

0

和yebmouxing一样,我也无法理解这个

 xhr.getResponseHeader('Set-Cookie');

方法无效。即使我在服务器上将HTTPOnly设置为false,它也只会返回null。

我也编写了一个简单的js帮助函数来从文档中获取cookie。这个函数非常基本,只有在您自己知道附加信息(寿命、域、路径等等)时才能起作用:

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 "";
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接