javascript - FB.getLoginStatus 在 Chrome 中不起作用,即使沙盒禁用

标签 javascript ruby-on-rails omniauth

我按照 railscast 在我的站点中添加了“使用 Facebook 登录”功能,登录没有问题。但是当尝试注销时,即使我在 facebook 开发人员应用程序设置中禁用沙盒模式(如其他一些讨论中所建议的),FB.getLoginStatus 似乎也从未起火:

(function() {
  jQuery(function() {
    $('body').prepend('<div id="fb-root"></div>');
return $.ajax({
  url: "" + window.location.protocol + "//connect.facebook.net/en_US/all.js",
  dataType: 'script',
  cache: true
});
});

window.fbAsyncInit = function() {
FB.init({
  appId: 'xxxxxomittedxxxxx',
  cookie: true,
  status: true,
  xfbml: true,
  oauth: true
    });
$('#sign_in').click(function(e) {
  e.preventDefault();
  return FB.login(function(response) {
    if (response.authResponse) {
      return window.location = '/auth/facebook/callback';
    }
  });
});
return $('#sign_out').click(function(e) {
  FB.getLoginStatus(function(response) {
    if (response.authResponse) {
      return FB.logout(response.authResponse);
    }
  });
  return true;
});
 };

}).call(this);

我知道 FB.getLoginStatus 永远不会进入(或不起作用)的原因是我将正文替换为:

  FB.getLoginStatus(function(response) {
    return alert("I am here!");
  });

点击“注销”时我看不到我的提醒。

我正在运行具有相同行为的 Chrome 和 Firefox。任何人都可以帮助发现我错过了什么吗?非常感谢。

让我更具体地描述一下我遇到的“行为”:

  1. 第一次从 mysite.com 使用 Facebook 登录 Facebook 登录窗口会弹出并询问电子邮件和密码,我可以完美地登录到我的网站并按预期工作
  2. 然后我点击 mysite.com/users/1 中的 sign_out 按钮,看起来可以正常退出。
  3. 然后再次从 mysite.com 使用 Facebook 登录,现在不再弹出 Facebook 登录窗口,直接登录 mysite.com/users/1,无需询问电子邮件和密码!
  4. 如果我打开另一个浏览器窗口并转到 facebook.com 并从那里注销,那么当我从 mysite.com 使用 Facebook 登录时,它现在会弹出一个 Facebook 登录窗口并询问我的电子邮件和密码。<

我希望我的网站表现:“当从 mysite.com/users/n 注销并再次从 mysite.com 使用 Facebook 登录时,将弹出 Facebook 登录窗口”

有人可以帮忙吗?非常感谢。

编辑:

进一步调查发现“根本”原因可能仍然是:注销在登录路由的不同路由(或页面)下,FB.getLoginStatus 无法在 mysite.com/signout 下触发。来自 firebug 的错误消息表明“应用程序配置不允许给定的 URL。应用程序的设置不允许一个或多个给定的 URL。它必须与网站 URL 或 Canvas URL 匹配,或者域必须是应用域之一的子域。”

为了证明这是路由问题,我将注销链接放在与登录路由相同的路由(页面)中,这是“使用 Facebook 登录的网站”中指定的根路由 mysite.com,一切正常并且可以按预期注销:

<%= link_to "sign out facebook", "#" , id: "sign_out" %>

顺便修改 sign_out js 以消除 FB.logout(response.authResponse) uncaught [object Object] 错误,因为 FB.logout 期望函数作为参数:

return $('#sign_out').click(function(e) {
  FB.getLoginStatus(function(response) {
    if (response.authResponse) {
      FB.logout();
    }
  }, true);
});
};

因此,最重要的是:FB.getLoginStatus 可能仍然存在无法处理来自与登录路由不同的路由的调用的错误。 (我用 Chrome、Firefox 和 Safari 进行了测试,它们的行为都相同,但对于 IE10 则不然。不知何故,IE10 甚至可以在不同的路径上退出。)

有类似问题的人有什么意见吗?请指教。非常感谢您。

最佳答案

尝试将 true 作为第二个参数添加到 getLoginStatus,如 FB 开发文档中所述:

FB.getLoginStatus(function(response) {
  // this will be called when the roundtrip to Facebook has completed
}, true);

这应该避免缓存。 另一种选择是订阅事件:

FB.Event.subscribe('auth.login', function(response) {
  // do something with response
});

全部来自here

如果您有任何问题,请发表评论。

编辑:

我稍微修改了你的脚本,删除了不需要的代码部分。您有太多不需要的返回。我尝试在这个修改后的脚本中注销,它可以按你的需要工作。 事件订阅用于检查目的。

<head>
    <title>Exam entry</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
</head>
<body>
    <div id="fb-root"></div>

    <input type="button" value="Sign in" id="sign_in" />
    <input type="button" value="Sign out" id="sign_out" />

    <script type="text/javascript">
        window.fbAsyncInit = function () {
            FB.init({
                appId: '586844044669652',
                cookie: true,
                status: true,
                xfbml: true
            });


            // Here we subscribe to the auth.authResponseChange JavaScript event. This event is fired
            // for any authentication related change, such as login, logout or session refresh. This means that
            // whenever someone who was previously logged out tries to log in again, the correct case below 
            // will be handled. 
            FB.Event.subscribe('auth.authResponseChange', function (response) {
                // Here we specify what we do with the response anytime this event occurs. 
                if (response.status === 'connected') {
                    // The response object is returned with a status field that lets the app know the current
                    // login status of the person. In this case, we're handling the situation where they 
                    // have logged in to the app.
                    testAPI();
                } /*else if (response.status === 'not_authorized') {
                    // In this case, the person is logged into Facebook, but not into the app, so we call
                    // FB.login() to prompt them to do so. 
                    // In real-life usage, you wouldn't want to immediately prompt someone to login 
                    // like this, for two reasons:
                    // (1) JavaScript created popup windows are blocked by most browsers unless they 
                    // result from direct interaction from people using the app (such as a mouse click)
                    // (2) it is a bad experience to be continually prompted to login upon page load.
                    FB.login();
                } else {
                    // In this case, the person is not logged into Facebook, so we call the login() 
                    // function to prompt them to do so. Note that at this stage there is no indication
                    // of whether they are logged into the app. If they aren't then they'll see the Login
                    // dialog right after they log in to Facebook. 
                    // The same caveats as above apply to the FB.login() call here.
                    FB.login();
                }*/
            });


            $('#sign_in').click(function (e) {
                e.preventDefault();
                FB.login(function (response) {
                    if (response.authResponse) {
                        //return window.location = '/auth/facebook/callback';
                    }
                });
            });
            $('#sign_out').click(function (e) {
                FB.logout(function (response) {
                    console.log("Here logout response", response);
                });
            });

        };

        // Here we run a very simple test of the Graph API after login is successful. 
        // This testAPI() function is only called in those cases. 
        function testAPI() {
            console.log('Welcome!  Fetching your information.... ');
            FB.api('/me', function (response) {
                console.log('Good to see you, ' + response.name + '.');
            });
        }

        // Load the SDK asynchronously
        (function (d) {
            var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
            if (d.getElementById(id)) { return; }
            js = d.createElement('script'); js.id = id; js.async = true;
            js.src = "//connect.facebook.net/en_US/all.js";
            ref.parentNode.insertBefore(js, ref);
        }(document));
    </script>
</body>

关于javascript - FB.getLoginStatus 在 Chrome 中不起作用,即使沙盒禁用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17478429/

相关文章:

ruby-on-rails - 将随机网址参数传递给OmniAuth

ruby-on-rails-4 - 捆绑更新后 FB-omniauth 损坏,凭据无效

ruby-on-rails-3 - 覆盖在omniauth gem中设置的默认范围

javascript - 我想在每次单击按钮时执行一个函数使用 JQuery

JavaScript addEventListener 与事件和绑定(bind)变量

ruby-on-rails - Ruby on Rails,从 secrets.yml 中检索 API key

css - 使用自定义字体的 rails 和 bootstrap?

javascript - 通过curl获取数据时在新标签页(Javascript)中打开PDF

javascript - 站点地图树缩进可视化

ruby-on-rails - 从 Rails 应用程序中监视数据库表的外部更改