9

我正在尝试在我的应用程序中使用 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 中无缝运行吗?

4

2 回答 2

4

如果您希望使用本机 ajax 或 jquery ajax,请去掉 async:false。它对我有用。

为了进一步兼容旧浏览器,我建议使用http://easyxdm.net/wp/。EasyXDM 方法是使用 iframe hack,它要求您将 html 文件放在要进行 ajax 调用的主机上。这将是强制异步的,是的。但是这个easyXDM的好处是你不必担心cors headers。

于 2013-02-06T23:44:21.843 回答
4

首先有几个观察:

  • 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”标头的模式匹配。

于 2013-07-30T21:18:21.900 回答