为什么jQuery的.ajax()方法不发送我的会话cookie?

通过$.ajax()login到一个网站后,我想发送第二个$.ajax()请求到该网站 – 但是当我检查使用FireBug发送的头,没有会议cookie被包括在请求。

我究竟做错了什么?

如果您所调用的url与您的调用脚本位于同一个域中,那么AJAX调用只会发送Cookie。

这可能是一个跨域问题。

也许你试图在www.domain-a.com上调用一个URL,而你的调用脚本在www.domain-b.com (换句话说:你做了一个跨域调用,在这种情况下浏览器不会发送任何cookie保护您的隐私)。

在这种情况下,您的select是:

  • 写一个驻留在域-b上的小代理,并将你的请求转发到域-a。 您的浏览器将允许您调用代理,因为它与调用脚本位于同一台服务器上。
    这个代理然后可以configuration你接受一个cookie名称和值的参数,它可以发送到域a。 但是为了这个工作,你需要知道cookie的名字并且在你的域名上给你的服务器赋值 – 一个想要authentication的服务器。
  • 如果您正在获取JSON对象,请尝试使用JSONP请求。 jQuery支持这些。 但是你需要在domain-a上改变你的服务,以便返回有效的JSONP响应。

很高兴,如果这有助于一点点。

我在跨域scheme中操作。 在login期间,远程服务器正在返回Set-Cookie头和Access-Control-Allow-Credentials设置为true。

下一个调用远程服务器的ajax应该使用这个cookie。

CORS的Access-Control-Allow-Credentials可以允许跨域logging。 查看https://developer.mozilla.org/En/HTTP_access_control的示例。;

对我来说,这似乎是一个在JQuery中的错误(或者至less在下一个版本中的function)。

更新:

  1. Cookie不会自动从AJAX响应设置(引用: http : //aleembawany.com/2006/11/14/anatomy-of-a-well-designed-ajax-login-experience/ )

    为什么?

  2. 您无法从响应中获取Cookie的价值以手动设置( http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-getresponseheader

    我很困惑..

    应该有一种方法来要求jquery.ajax()来设置XMLHttpRequest.withCredentials = "true"参数。

解答:您应该使用http://api.jquery.com/jQuery.ajax/的; xhrFields参数

文档中的示例是:

 $.ajax({ url: a_cross_domain_url, xhrFields: { withCredentials: true } }); 

服务器正确回答这个请求也很重要。 在这里复制来自@Frédéric和@Pebbl的精彩评论:

Important note: when responding to a credentialed request, server must specify a domain, and cannot use wild carding. The above example would fail if the header was wildcarded as: Access-Control-Allow-Origin: *

所以当请求是:

 Origin: http://foo.example Cookie: pageAccess=2 

服务器应该回应:

 Access-Control-Allow-Origin: http://foo.example Access-Control-Allow-Credentials: true [payload] 

否则有效载荷将不会被返回到脚本。 请参阅: https : //developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials

运用

 xhrFields: { withCredentials:true } 

作为我的jQuery ajax调用的一部分只是解决scheme的一部分。 我还需要在我的资源的OPTIONS响应中返回头文件:

 Access-Control-Allow-Origin : http://www.wombling.com Access-Control-Allow-Credentials : true 

在OPTIONS调用的响应标题中只有一个允许的“origin”是非常重要的,而不是 “*”。 我通过从请求中读取出处并将其填充到响应中来达到这一目的 – 可能绕过了限制的原始原因,但在我的使用案例中,安全性并不是最重要的。

我认为值得明确提及只需要一个来源的要求,因为W3C标准确实允许使用空格分隔列表,但Chrome并没有! 注意“实践”一点。

把这个放在你的init函数中:

 $.ajaxSetup({ xhrFields: { withCredentials: true } }); 

它会工作。

对这个问题已经有很多好的回答,但是我认为这样做可能会有所帮助,因为cookie的域名匹配会导致会话cookie被发送,但是由于AJAX请求是被做成一个不同的子域名。 在这种情况下,我有一个分配给* .mydomain.com域的cookie,并且我希望它被包含在一个AJAX请求中去到different.mydomain.com 。“默认情况下,cookie不会被发送。你不需要在session cookie上禁用HTTPONLY来解决这个问题。你只需要做什么womblingbuild议( https://stackoverflow.com/a/23660618/545223 ),然后执行以下操作。

1)将以下内容添加到您的ajax请求中。

 xhrFields: { withCredentials:true } 

2)将以下内容添加到不同子域中的资源的响应标头中。

 Access-Control-Allow-Origin : http://original.mydomain.com Access-Control-Allow-Credentials : true 

我有这个相同的问题,并做一些检查我的脚本只是根本没有得到sessionid cookie。

我通过查看浏览器中的sessionid cookie值,发现我的框架(Django)默认将HttpOnly传递给sessionid cookie。 这意味着脚本无法访问sessionid值,因此不会将其与请求一起传递。 当有那么多的东西使用需要访问限制的Ajax时,HttpOnly会成为默认值。

为了解决这个问题,我改变了一个设置(SESSION_COOKIE_HTTPONLY = False),但是在其他情况下,它可能是一个cookiepath上的“HttpOnly”标志

在尝试login之前,您必须初始化会话。

对于PHP,你必须这样做

 session_start(); 

在开始loginajax调用的页面上。

这样会创buildSESSIONID并存储浏览器cookie。 并在ajax调用期间与请求头一起发送,如果您对同一个域执行ajax请求

对于后续的ajax调用,浏览器将使用最初创build并存储在浏览器cookie中的SESSIONID ,除非我们清除浏览器cookie或者注销(或者设置另一个cookie)

如果您正在localhost上开发localhostlocalhost的端口(如localhost:8080 ,除了上述回答中所述的步骤之外,还需要确保您没有在Set-Cookie标头中传递域值。
您不能在Set-Cookie头中将域设置为localhost – 这是不正确的 – 只是省略域。

本地主机上的Cookie与显式域名 , 为什么不会在本地主机上创buildcookie?

也许不是100%回答这个问题,但是我偶然发现了这个线程,希望能解决一个会话问题,当时ajax从innovastudio编辑器的assetmanager发布一个file upload。 最终解决scheme很简单:他们有一个flash上​​传器。 禁用(设置

 var flashUpload = false; 

在asset.php),灯开始闪烁。

由于这些问题可能非常难以debugging,我发现在上传处理程序中添加如下内容会使您(在本例中为我)处于正确的轨道上:

 $sn=session_name(); error_log("session_name: $sn "); if(isset($_GET[$sn])) error_log("session as GET param"); if(isset($_POST[$sn])) error_log("session as POST param"); if(isset($_COOKIE[$sn])) error_log("session as Cookie"); if(isset($PHPSESSID)) error_log("session as Global"); 

深入了解日志,我迅速发现了没有发送cookie的丢失会话。