如果用户未登录Facebook,则FB.init期间不会触发auth.statusChange

auth.statusChange doesn't fire during FB.init if the user isn't logged in to facebook

我想知道是否有人找到了针对我所遇到行为的解决方法。

以下面的代码为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
window.fbAsyncInit = function() {
        FB.init({
          appId      : '[----removed-------]', // App ID
          channelUrl : 'http://localhost/channel.html', // Channel File
          status     : true, // check login status
          cookie     : true, // enable cookies
          xfbml      : true  // parse XFBML
        });    
        // Additional initialization code here

        FB.Event.subscribe('auth.statusChange',fbLoginStatus);

        console.log("getloginstatus");

        FB.getLoginStatus(fbLoginStatus);

使用状态设置为true的FB.init,实际上根据Facebook文档调用getLoginStatus()。但是,这显然是预期的行为,它将不会触发事件auth.statusChange,因为默认值是"未知",并且"未登录"的值也是"未知"(即使它可以被知道!!) )

因此,如果我还想响应未登录facebook的用户,则必须显式调用FB.getLoginStatus(),并将状态设置为true。

问题是,如果用户不是"注销"用户,这将导致该函数被调用两次。

是否有一种巧妙的方法来阻止这种情况的发生?
我认为我唯一的选择可能是调用一个不同的函数来处理auth更改事件。.


为此,我最好的解决方案是在fb.init选项中将status设置为" false",然后分别显式调用getloginstatus。

如果获取的登录状态未知(即注销),我订阅了状态更改事件,并按照通常的方式显示登录按钮。然后,当用户登录时,状态更改将按预期触发。


理论上应该为您节省往返的更好的解决方案如下(咖啡,但可以轻松地翻译成javascript):

1
2
3
4
5
6
7
8
9
10
11
FB.init
  appId: appId
  channelUrl: channelUrl
  status: true     # Check Facebook Login status on init
  cookies: true
  xfbml: false

FB.getLoginStatus (response) =>
  @parseResponse(response)
  FB.Event.subscribe 'auth.statusChange', @parseResponse
  FB.Event.subscribe 'auth.authResponseChange', @parseResponse

我们仍然使用手动的getLoginStatus在未知用户时触发,但是这次我们仍然使用'status:true',以便在调用getLoginStatus时已经缓存了登录状态。通过仅在getLoginStatus触发后预订相关事件,我们确保处理方法parseResponse在加载时仅被调用一次。


您可以检查在getLoginStatus中传递真实参数后返回的响应:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
window.fbAsyncInit = function() {
    FB.init({
        appId  : '',
        status : true,
        cookie : true,
        xfbml  : true,
    });

    FB.getLoginStatus( function(response) {
        //console.log(response);
        if (response.status === 'connected') {
            var accessToken = response.authResponse.accessToken;
            alert(accessToken);
        } else if (response.status === 'not_authorized') {
            //login function
        } else {
            //login function
        }
    }, true);

    FB.Event.subscribe('auth.authResponseChange', function(response) {
        //console.log('The status of the session changed to: '+response.status);
        window.location.reload();
    });
};

如果将status设置为true,则FB.getLoginStatus响应对象将由SDK缓存,随后对FB.getLoginStatus的调用将从此缓存的响应中返回数据。

要解决此问题,您必须在第二个参数设置为true的情况下调用FB.getLoginStatus,以强制往返于Facebook-有效地刷新响应对象的缓存。

FB文档:https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/