通过$.ajax()登录到某个站点后,我试图向该站点发送第二个$.ajax()请求-但是当我检查使用FireBug发送的标头时,请求中没有会话cookie。

我在做什么错?

评论

Web cookie可能紧随ajax的cookie,而FireBug可能会捕获首页cookie。

我没有明白你的意思,但是我可以说,如果我将请求URL粘贴到浏览器地址栏中,然后再次检查Firebug,我可以看到发送到服务器的headres中的cookie。有解决方案吗?

因此,我认为ajax也将以与浏览器相同的方式处理

您正在使用什么代码?

浏览器仍会在ajax请求,jquery或其他情况下创建服务器设置的cookie。您是否检查了对ajax请求的响应,并确保要设置的cookie从服务器返回?服务器代码可能存在问题,甚至没有设置cookie等。

#1 楼

如果您所调用的url与您的调用脚本位于同一域中,则AJAX调用仅发送Cookie。

这可能是跨域问题。

也许您尝试当您的调用脚本位于www.domain-a.com上时,请从www.domain-b.com调用url(换句话说:您进行了跨域调用,在这种情况下浏览器将不会发送任何cookie来保护您的隐私)。

如果您的选择是:


编写一个小的代理,该代理驻留在domain-b上并将您的请求转发到domain-a。您的浏览器将允许您调用代理,因为它与调用脚本位于同一服务器上。然后您可以将其配置为接受可以发送到domain-a的cookie名称和值参数。但是要使其正常工作,您需要知道cookie的名称和服务器在域上的值-要进行身份验证。
如果要获取JSON对象,请尝试使用JSONP请求。 jQuery支持这些。但是您需要更改domain-a上的服务,以便它返回有效的JSONP响应。

有点帮助的话很高兴。

评论


还值得注意的是,可以将cookie设置为特定路径,因此,如果您使用path = / something设置了cookie,并且您正在请求/ another页面,则将不会发送该cookie。当您请求页面/内容时,cookie将按预期发送。因此,还要检查设置cookie的代码。

–样式
13年7月30日在20:45

jsonp请求发送coockies吗?

– albanx
2014年3月23日在11:25

@albanx是的,如果设置了我提到的要求。就像其他请求一样,这只是正常请求,因此会发送Cookie。

–流感
2014年3月24日15:31

@albanx这个其他相关问题包括如何使用自定义Cookie执行该JSONP请求的示例

– AntonioHerraizS
14年5月13日在16:17

根据Wikipedia上的JSONP,此方法被放弃以支持CORS

– Peter Dotchev
2015年11月5日9:05



#2 楼

我在跨域情况下进行操作。登录期间,远程服务器将返回Set-Cookie标头,并将Access-Control-Allow-Credentials设置为true。

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

CORS的Access-Control-Allow-Credentials在那里允许跨域日志记录。请查看https://developer.mozilla.org/zh-CN/HTTP_access_control以获取示例。

对我来说,这似乎像是JQuery中的错误(或者至少是下一版本中的功能)。

更新:



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

为什么?


您无法从响应中获取cookie的值来进行设置手动(http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-getresponseheader)

我很困惑。.

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


ANSWER:
您应该使用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/zh-CN/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials

评论


太好了!我添加使用此+在服务器端将Access-Control-Allow-Credentials标头设置为true

–Frédéric
2012年11月29日12:26

以及在“标题授权”处,请求正文处的那些凭据?

–弗朗西斯科·科拉莱斯·莫拉莱斯
2014年3月20日在21:25

感谢您的回答:)只是一个快速补充,可能值得一提。重要说明:在响应凭据请求时,服务器必须指定域,并且不能使用通配符。如果标题的通配符为:Access-Control-Allow-Origin:*developer.mozilla.org/en-US/docs/Web/HTTP/…,则上述示例将失败。

– Pebbl
14年8月27日在16:52

不幸的是,这些都不对我有用。如果我从AngularJS运行相同的请求,则可以运行,但从jQuery运行,即使有这些建议,会话Cookie也不会通过。 (jQuery v2.1.1)

–地线学
16年5月14日在18:29



(O.O)您从各种痛苦的时刻中拯救了我。完美的答案!谢谢!我需要将这些添加到我的网站的公共根.htaccess中:标头设置了Access-Control-Allow-Origin“ localhost”标头设置了Access-Control-Allow-Credentials“ true”

– Vinay Vissh
17年4月4日在19:10

#3 楼

在我的jQuery ajax调用中使用

xhrFields: { withCredentials:true }


只是解决方案的一部分。我还需要从我的资源的OPTIONS响应中返回标头:

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


重要的是,在响应的标头中只有一个允许的“来源” OPTIONS呼叫而不是“ *”。我通过读取请求中的来源并将其填充回响应中来实现这一目的-可能绕过了限制的原始原因,但是在我的用例中,安全性不是最重要的。

我认为值得一提的是仅要求一个来源,因为W3C标准确实允许使用空格分隔列表-但Chrome不允许!
http://www.w3 .org / TR / cors /#access-control-allow-origin-response-header
“在实践中”位。

#4 楼

将其放在您的init函数中:

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


它将起作用。

评论


你救了我的一天!在方法级别,withCredentials对我不起作用。但是像这样的全局性终于可以了!谢谢。

– Paulius Matulionis
15年4月10日在10:54

小心,因为它将向所有请求发送cookie,向其他域发送以太(这不是期望的,并且要求通过Access-Control-Allow-Credentials失败请求)

– gdbdable
19年8月23日在14:06

#5 楼

对于这个问题已经有很多好的回答,但是我认为澄清一下由于cookie域匹配而希望发送会话cookie的情况可能会有所帮助,因为AJAX请求是被设置到另一个子域。在这种情况下,我有一个分配给* .mydomain.com域的cookie,并且希望将它包含在对different.mydomain.com的AJAX请求中。”默认情况下,不会发送该cookie。您无需禁用会话cookie上的HTTPONLY即可解决此问题,只需执行建议的摇晃操作(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


#6 楼

在尝试了其他解决方案并且仍然无法使之工作之后,我发现了我的问题所在。我将contentType从“ application / json”更改为“ text / plain”。

$.ajax(fullUrl, {
    type: "GET",
    contentType: "text/plain",
    xhrFields: {
         withCredentials: true
    },
    crossDomain: true
});


#7 楼

我遇到了同样的问题,做了一些检查,我的脚本只是根本没有获得sessionid cookie。

我通过查看浏览器中我的框架(Django)正在传递的sessionid cookie值来弄清楚默认为HttpOnly的sessionid cookie。这意味着脚本无法访问sessionid值,因此不会将其与请求一起传递。荒谬的是,当许多东西使用Ajax且需要访问限制时,HttpOnly将成为默认值。

要解决此问题,我更改了设置(SESSION_COOKIE_HTTPONLY = False),但在其他情况下,它可能是cookie路径上的“ HttpOnly”标志

评论


不要这样做。它允许客户端脚本访问会话cookie,这是最常见的XSS攻击媒介。 owasp.org/index.php/HttpOnly

–杰森·埃尔金(Jason Elkin)
17年5月9日在14:42

#8 楼

如果要在localhost或localhost上的端口(例如localhost:8080)上进行开发,则除了上述答案中描述的步骤外,还需要确保未在Set-Cookie标头中传递域值。
您不能在Set-Cookie标头中将域设置为localhost-这是不正确的-仅忽略域。

请参阅具有显式域的localhost上的cookie,为什么asp.net不能在localhost中创建cookie?

#9 楼

在本地主机和开发环境下,仅花2美分就可以设置PHPSESSID Cookie。我在locahost上对我的REST API端点进行了AJAX调用。说它的地址是mysite.localhost/api/member/login/(在我的开发环境中是虚拟主机)。


当我在Postman上执行此请求时,一切正常,并且在响应中设置了PHPSESSID。
当我通过Browsersync代理页面通过AJAX请求此终结点(例如,从我的浏览器地址行中的122.133.1.110:3000/test/api/login.php,请参阅域与mysite.localhost之间的域不同)PHPSESSID不会出现在cookie中。
当我直接从该页面上发出此请求时设置相同的域(即mysite.localhost/test/api/login.php)PHPSESSID就可以了。

所以这是一个跨域起源请求cookie问题,如上面@flu回答中所述

#10 楼

添加我的方案和解决方案以防其他人使用。使用RESTful API时遇到类似情况。我托管HTML / Script / CSS文件的Web服务器和Application Server公开API托管在同一域中。
但是路径不同。


Web服务器-mydomain / webpages / abc.html



使用abc.js进行设置名为mycookie的cookie


应用程序服务器-mydomain / webapis / servicename。


对其进行api调用的

我原本以为mydomain / webapis / servicename中的cookie并尝试读取它,但是没有发送。
从答案中读取评论后,我检查了浏览器的开发工具,
mycookie的路径设置为“ / webpages”,因此在对


mydomain / webapis / servicename


的服务调用中不可用,因此从jquery设置cookie时,这就是我做到了-

$.cookie("mycookie","mayvalue",{**path:'/'**});


#11 楼

也许不是100%回答这个问题,但是我偶然发现了这个线程,希望当从anovastudio编辑器的assetmanager进行ajax发布文件上传时解决会话问题。
最终,解决方案很简单:它们具有闪存功能-上载器。禁用它(在asset.php中设置
var flashUpload = false;   


),然后指示灯又开始闪烁。

因为这些问题很难调试我发现在上传处理程序中添加以下内容将使您(在这种情况下为我)设置在正确的轨道上:

$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。

评论


我认为上面的示例不起作用,因为当没有会话cookie时,$ sn的值是多少? (一个随机值,或者可能为null),或者,用户可以从GET值中设置session_name,例如session_name(isset($ _ GET ['sess']]?$ _GET ['sess']:null); session_start();这样,他们会得到工作

–钢脑
2014年12月21日下午2:30

这正是我发现问题的方式:从此Flash上​​传器发布内容时没有会话。由于使用GET变量会话标识符不是一个好主意,并且cookie无法正常工作,因此我将其丢弃。谁在乎,闪光灯反正已经成为过去。

–埃勒特·范·科珀伦
2014-12-22 12:22