通过$.ajax()
站点登录后,我尝试$.ajax()
向该站点发送第二个请求-但是,当我检查使用FireBug发送的标头时,请求中没有会话cookie。
我究竟做错了什么?
通过$.ajax()
站点登录后,我尝试$.ajax()
向该站点发送第二个请求-但是,当我检查使用FireBug发送的标头时,请求中没有会话cookie。
我究竟做错了什么?
Answers:
如果您要调用的URL与您的调用脚本位于同一域中,则AJAX调用仅发送Cookie。
这可能是跨域问题。
也许您www.domain-a.com
是在调用脚本打开时尝试从url 调用的www.domain-b.com
(换句话说:您进行了跨域调用,在这种情况下浏览器将不会发送任何cookie来保护您的隐私)。
在这种情况下,您的选择是:
高兴的是,即使有所帮助。
path=/something
而您正在请求页面/another
,则将不会发送该cookie。当您请求页面时/something
,cookie将按预期发送。因此,还要检查设置cookie的代码。
我在跨域情况下进行操作。登录期间,远程服务器将返回Set-Cookie标头以及将其Access-Control-Allow-Credentials
设置为true。
对远程服务器的下一个ajax调用应使用此cookie。
CORS Access-Control-Allow-Credentials
允许跨域日志记录。检查https://developer.mozilla.org/En/HTTP_access_control以获取示例。
对我来说,这似乎是JQuery中的错误(或至少在下一版本中是新功能)。
更新:
不会通过AJAX响应自动设置Cookie(引用: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"
参数的方法。
解答:
您应该使用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
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: *
developer.mozilla.org/en-US/docs/Web/HTTP/...
使用
xhrFields: { withCredentials:true }
作为我的jQuery ajax调用的一部分,仅是解决方案的一部分。我还需要从资源中在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 注意“实践”位。
将其放在您的init函数中:
$.ajaxSetup({
xhrFields: {
withCredentials: true
}
});
会的。
对于这个问题已经有很多好的回答,但是我认为澄清一下由于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
在尝试了其他解决方案并且仍然无法使之工作之后,我发现了我的问题所在。我将contentType从“ application / json”更改为“ text / plain”。
$.ajax(fullUrl, {
type: "GET",
contentType: "text/plain",
xhrFields: {
withCredentials: true
},
crossDomain: true
});
我遇到了同样的问题,做了一些检查我的脚本只是根本没有获取sessionid cookie。
通过查看浏览器中的sessionid cookie值,我发现我的框架(Django)正在使用默认的HttpOnly传递sessionid cookie。这意味着脚本无法访问sessionid值,因此不会将其与请求一起传递。荒谬的是,当许多东西使用Ajax且需要访问限制时,HttpOnly将成为默认值。
为了解决这个问题,我更改了设置(SESSION_COOKIE_HTTPONLY = False),但在其他情况下,它可能是cookie路径上的“ HttpOnly”标志
如果要localhost
在localhost 上或在localhost 上进行开发localhost:8080
,除了上面的答案中描述的步骤外,还需要确保没有在Set-Cookie标头中传递域值。
您不能localhost
在Set-Cookie标头中将域设置为-这是不正确的-仅忽略域。
请参阅具有显式域的localhost上的Cookies,以及asp.net为什么不在localhost中创建cookie?
在本地主机和开发环境下,仅花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设置就很好。
添加我的方案和解决方案以防其他人使用。使用RESTful API时遇到类似情况。我托管HTML / Script / CSS文件的Web服务器和Application Server公开API托管在同一域中。但是,路径是不同的。
网络服务器-mydomain / 网页 /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:'/'**});
也许不是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。
session_name(isset($_GET['sess']) ? $_GET['sess'] : null);session_start();
就这样,他们会得到一个工作的事情