我正在尝试在我的应用程序中使用Ajax身份验证,并且似乎已经使它工作了,除了firefox似乎没有在后续请求的" cookie"请求标头中向服务器发送正确的jessionid,而chrome这样做就很好了。。 这是登录功能:
$.ajaxSetup({
xhrFields: {
withCredentials : true
}
})
function sudoLogin(callback){
$.ajax({
url : HOST +"/ProperApp/j_spring_security_check",
type :"POST",
data : $("#login").serialize(),
dataType: 'json',
async : false,
success: function(result) {
if (result.login) {
callback(true);
} else {
callback(false);
}
}
})
}
在firefox的响应中,我可以看到已设置cookie,并且成功回调被称为:
Set-Cookie JSESSIONID=81235e7ff741e941c1e078afee5c; Path=/ProperApp; HttpOnly
但是,在诸如此类的后续请求中,未发送cookie:
function getUserDeets(callback){
$.ajax({
url : HOST+"/ProperApp/userData",
type :"GET",
async : false,
dataType : 'json',
xhrFields: {
withCredentials: true
},
success : function(data){
callback(data);
}
})
}
$('#submitLogin').click(function(){
sudoLogin(function(loggedIn){
if(loggedIn){
//window.location ="sudoIndex2.php";
getUserDeets(function(user){
alert(user);
})
}
else
alert("login failure");
});
});
在Chromium中,请求包含cookie标头,并且成功回调被正确调用:
...
Connection:keep-alive
Cookie:JSESSIONID=8129ef67b59180f9f21383cba850
Host:localhost:8080
Origin:http://localhost:8000
Referer:http://localhost:8000/loginSignup.php
...
但是,在Firefox中,请求标头不包含cookie标头,并且永远不会调用成功:
...
Connection keep-alive
Host localhost:8080
Origin http://localhost:8000
Referer http://localhost:8000/loginSignup.php
...
我已经在服务器端创建了一个ajax过滤器,我认为应该允许这种情况发生:
response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
response.setHeader("Access-Control-Max-Age","360");
response.setHeader("Access-Control-Allow-Credentials","true");
response.setHeader("Access-Control-Allow-Headers","Authorization");
知道为什么它可以在Chrome而不是Firefox中无缝运行吗?
可能是跨域安全问题...总是可以将cookie值作为数据发送并在客户端进行更新
知道我该如何解决吗? 我认为不应由客户端脚本访问cookie。
在尝试一切可能的方法来使Firefox变得更好时,花了2 1/2天的时间,我终于放弃了,最终使用了嵌入的iframe,该iframe是与Web服务托管在同一服务器上的登录表单。 我能想到的唯一解释是,Firefox在处理跨域请求中的cookie方面更加严格,而chrome更松懈。 真正困扰我的是该软件并没有真正跨域通信,只是在不同的端口上。 那好吧。
不同的端口是跨域的
愚蠢的问题,但是您如何处理会话路径呢?
首先有几个观察结果:
OP(原始帖子)正在处理跨域XHR,因为AustinR使用的端口不同(如果主机,域或端口的任何部分不同,则浏览器会将XHR视为跨域)
跨域XHR需要在服务器上设置正确的CORS标头
OP中的javascript看起来不错,但async:false除外,理想情况下应将其设置为async:true(或跳过,因为设置默认为true)
参考给定的示例,我将从以下CORS标头开始:
response.setHeader("Access-Control-Allow-Origin","http://localhost:8000"); // use a wildcard (*) as the 2nd parameter if you want to be less restrictive
response.setHeader("Access-Control-Max-Age","360");
response.setHeader("Access-Control-Allow-Credentials","true");
response.setHeader("Access-Control-Allow-Methods","GET");
response.setHeader("Access-Control-Allow-Headers","Origin");
response.setHeader("Access-Control-Expose-Headers","Access-Control-Allow-Origin");
最后一个CORS设置" Access-Control-Expose-Headers"特别有用,因为它使您有机会对服务器在HTTP响应中发送的标头进行故障排除。
检查Firebug网络面板中的响应标头部分,以获取CORS标头。
您请求的" Origin"标头应与服务器响应的" Access-Control-Allow-Origin"标头的模式匹配。
你说的没错。 实际的问题是我使用了*(通配符)符号。 我一输入直接主机名-FF就开始发送cookie。 因此,FF在这方面似乎更具限制性。 您应定义要发送的Cookie的确切来源。
如果您希望使用本机ajax或jquery ajax,则删除async:false。它为我工作。
为了进一步兼容旧版浏览器,我建议使用http://easyxdm.net/wp/。 EasyXDM方法是使用iframe hack,该iframe hack要求您将html文件放置在要进行ajax调用的主机上。这将被强制异步,是的。但是,使用此easyXDM的好处在于,您不必担心cors标头。
我最终在远程主机上使用了iframe作为登录表单。 我没有使用easyxdm,它很容易滚动自己并使用postMessage api将数据从iframe发送到浏览器。 因此,虽然不理想,但这种方法有效。