通过$.ajax()
登录到某个网站后,我尝试向该网站发送第二个$.ajax()
请求 - 但是当我检查使用FireBug发送的标头时,没有包含会话Cookie在请求中。
我做错了什么?
答案 0 :(得分:359)
我在跨域方案中运行。在登录期间,远程服务器返回Set-Cookie标头以及Access-Control-Allow-Credentials
设置为true。
对远程服务器的下一个ajax调用应使用此cookie。
CORS的Access-Control-Allow-Credentials
允许跨域日志记录。查看https://developer.mozilla.org/En/HTTP_access_control以获取示例。
对我来说,这似乎是JQuery中的一个错误(或者至少是下一版本中的功能)。
更新:
Cookie不会自动从AJAX响应中设置(引用:http://aleembawany.com/2006/11/14/anatomy-of-a-well-designed-ajax-login-experience/)
为什么?
您无法从响应中获取cookie的值以手动设置(http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-getresponseheader)
我很困惑..
应该有一种方法可以让jquery.ajax()
设置XMLHttpRequest.withCredentials = "true"
参数。
<强>解答:强>
您应该使用xhrFields
$.ajax({
url: a_cross_domain_url,
xhrFields: {
withCredentials: true
}
});
参数
文档中的示例是:
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: *
服务器正确回答此请求也很重要。在这里复制@Frédéric和@Pebbl的好评:
Origin: http://foo.example
Cookie: pageAccess=2
所以当请求是:
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Credentials: true
[payload]
服务器应该回复:
{{1}}
否则有效负载不会返回脚本。请参阅:http://api.jquery.com/jQuery.ajax/
答案 1 :(得分:203)
如果您呼叫的网址与您的主叫脚本位于同一个域,则AJAX呼叫仅发送Cookie。
这可能是跨域问题。
当您的调用脚本在www.domain-a.com
上时,也许您尝试从www.domain-b.com
调用网址(换句话说:您进行了跨域调用,在这种情况下,浏览器不会向其发送任何Cookie保护您的隐私。)
在这种情况下,您的选项是:
如果这有点帮助的话,我很高兴。
答案 2 :(得分:46)
使用
xhrFields: { withCredentials:true }
作为我的jQuery ajax调用的一部分只是解决方案的一部分。我还需要在我的资源的OPTIONS响应中返回标头:
Access-Control-Allow-Origin : http://www.wombling.com
Access-Control-Allow-Credentials : true
重要的是只有一个允许&#34;起源&#34;在OPTIONS调用的响应标题中,不是&#34; *&#34;。我通过从请求中读取原点并将其填充回响应来实现这一点 - 可能绕过限制的原始原因,但在我的用例中,安全性并不是最重要的。
我认为值得明确提到只有一个来源的要求,因为W3C标准确实允许空格分隔列表 - 但Chrome没有! http://www.w3.org/TR/cors/#access-control-allow-origin-response-header 注意事项&#34;在实践中&#34;位。
答案 3 :(得分:39)
将它放在你的init函数中:
$.ajaxSetup({
xhrFields: {
withCredentials: true
}
});
它会起作用。
答案 4 :(得分:11)
对这个问题已经有很多好的回答了,但我认为澄清你希望发送会话cookie的情况可能会有所帮助,因为cookie域匹配,但它没有被发送,因为正在向不同的子域发出AJAX请求。在这种情况下,我有一个分配给 * .mydomain.com 域的cookie,我希望它包含在 different.mydomain.com的AJAX请求中“。默认情况下,cookie不会被发送。您不需要在会话cookie上禁用HTTPONLY来解决此问题。您只需要执行wombling建议的内容(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
答案 5 :(得分:5)
在尝试了其他解决方案后仍然没有让它工作,我发现问题出在我的案例中。我更改了#34; application / json&#34;中的contentType。 to&#34; text / plain&#34;。
$.ajax(fullUrl, {
type: "GET",
contentType: "text/plain",
xhrFields: {
withCredentials: true
},
crossDomain: true
});
答案 6 :(得分:3)
我遇到了同样的问题并且做了一些检查我的脚本只是没有得到sessionid cookie。
我通过查看浏览器中的sessionid cookie值得出结论,我的框架(Django)默认使用HttpOnly传递sessionid cookie。这意味着脚本无法访问sessionid值,因此不会将其与请求一起传递。当很多东西使用需要访问限制的Ajax时,HttpOnly会成为默认值,这有点荒谬。
要解决此问题,我更改了设置(SESSION_COOKIE_HTTPONLY = False),但在其他情况下,它可能是Cookie路径上的“HttpOnly”标志
答案 7 :(得分:0)
如果您正在使用localhost
或本地主机上的端口(例如localhost:8080
)进行开发,除了上述答案中描述的步骤之外,您还需要确保没有传递域值在Set-Cookie标题中。
您无法在Set-Cookie标头中将域设置为localhost
- 这是不正确的 - 只需省略域。
请参阅Cookies on localhost with explicit domain和Why won't asp.net create cookies in localhost?
答案 8 :(得分:0)
在本地主机和开发环境下,仅花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设置就很好。
这是@flu answer above
中提到的跨域起源请求cookie问题答案 9 :(得分:0)
添加我的方案和解决方案,以防其他人使用。使用RESTful API时遇到类似情况。我托管HTML / Script / CSS文件的Web服务器和暴露API的Application Server托管在同一域中。 但是路径是不同的。
网络服务器-mydomain / 网页 /abc.html
使用了 abc.js ,它设置了名为 mycookie
的cookie应用服务器-mydomain / webapis /服务名称。
进行了api调用
我期望mydomain / webapis / servicename中的cookie并尝试读取它,但未发送。 阅读答案的评论后,我签入了浏览器的开发工具, mycookie的路径设置为“ / 网页”,因此在对
的服务调用中不可用mydomain / webapis /服务名称
所以在通过jquery设置cookie时,这就是我所做的-
$.cookie("mycookie","mayvalue",{**path:'/'**});
答案 10 :(得分:-5)
也许不是100%回答这个问题,但我偶然发现了这个线程,希望在ajax-从innovastudio编辑器的assetmanager发布文件上载时解决会话问题。 最终解决方案很简单:他们有一个flash-uploader。禁用(设置
var flashUpload = false;
在asset.php中)并且指示灯再次闪烁。
由于这些问题很难调试,我发现在上传处理程序中添加如下内容会让你(好吧,在这种情况下我)在正确的轨道上:
$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。