检测Facebook会话的更改

时间:2012-03-18 12:49:16

标签: javascript facebook facebook-javascript-sdk

我的网站外观在很大程度上取决于用户是否通过Facebook登录,结果一旦发现Facebook会话中的任何变化对我来说非常重要,以便我能够适应该页面反映用户的登录状态。我讨厌对这类代码使用间隔和超时,因为事情可能变得非常混乱,但它似乎是唯一的选择(据我所知)。

我尝试过使用FB.subscribe(auth.statusChange),但这似乎并没有足够频繁且必然正确。也许我使用它错了?

我测试FB.subscribe(auth.statusChange)的方式只是每次触发时记录,并故意在另一个标签上登录和退出Facebook。事件似乎需要大约30分钟才能实际开火(而且并不总是开火)。这不仅难以测试,因为每次我必须等待30分钟,似乎它不一定正确地开火。我使用不正确吗?

我正在考虑使用的代码是这样的,但我不满意它,因为它使用超时/间隔:

window.fbAsyncInit=function(){
    // Initialize the Facebook object
    FB.init({
        appId:"123",
        status:true,
        cookie:true,
        xfbml:true,
        oauth:true
    });
    // Check the Facebook session status every 30 seconds
    setInterval(function(){
        FB.getLoginStatus(function(a){
            // Change the page look based on the facebook status
            fb_welcome(a.status)
        },true)}
    ,30000);
};

或者,我宁愿使用超时而不是间隔,但是这需要我将Facebook对象传递给另一个这样的函数:

// Check the Facebook session status every 30 seconds
setTimeout(function(){
    // Pass the Facebook object to the welcome function
    fb_welcome(FB);
,30000);

将FB对象传递给fbAsyncInit函数之外的另一个函数是不是一个坏主意?

3 个答案:

答案 0 :(得分:2)

实际上订阅auth.authResponseChange事件会更好。这在Event.subscribe文档中列为最佳实践。

  

对于大多数情况,您需要订阅auth.authResponseChange而不是auth.statusChange。响应以javascript数组的形式返回,未编码为JSON。

<强>更新
这样的似乎也不适合你,因为如果你打电话给Facebook的API,可能会不时调用它,可能还有其他情况,比如登录/注销。

Facebook JS-SDK中并不存在您所要求的内容,并且间隔似乎是一种选择。您可以设置一个仅调用FB.getLoginStatus的间隔,并保留事件订阅,因为如果检测到状态/ authResponse更改,将触发事件。

FB.Event.subscribe('auth.authResponseChange', function(authResponse){
  // authResponse changed
});

window.setInterval(FB.getLoginStatus, 30000);

答案 1 :(得分:1)

我有完全相同的问题。

我不是30秒间隔的忠实粉丝,因为我不得不这样做 ping我的服务器也知道我的用户在我的网站中的状态 因为我的facebook用户和普通用户也是因为 也许根据用户的行为(行动,没有必要) 依靠facebook,其他人没有)

所以,我的目标是只在javascript中执行getLoginStatus 用户要求实际需要呼叫Facebook的操作 在服务器端

我正在将FB Javascript SDK与PHP SDK结合使用。

所以我想我会做的

    在FB.Login中
  • :如果已连接,则执行服务器端身份验证 当令牌过期时,我设置了一个超时来执行getStatusLogin 仅刷新令牌
  • 由于auth.statusChange事件似乎仅在页面加载时触发 我将根据我站点中的用户状态实现操作 这一刻(页面加载)。
  • 当用户要求进行需要FB交互的操作时 - &gt; getLoginStatus

我看到的唯一问题是它会降低用户响应速度。 您如何看待我对每30秒x用户加载服务器的担忧?

<强>更新

  • 由于最令人讨厌的事情是令牌过期我只会在javascript调用getLoginStatus
  • 中实现自动刷新令牌感谢到setTimeout
  • 对于其他人,我将坚持一个更简单的解决方案,这是一个很好的服务器错误页面Facebook异常要求重新连接,如果:
    • 他们已经在我的应用程序之外注销了facebook,
    • 他们未经授权我的应用程序(因此他们不想使用它)。

在我的情况下,这两种可能性比第一种(令牌到期)更具传闻性。 所以KISS

答案 2 :(得分:1)

适用于更现代浏览器的解决方案是利用localStorage事件在浏览器标签之间传播状态更改。

订阅auth.authResponseChange并更新localStorage以反映状态:<​​/ p>

Private Sub CommandButton1_Click()

    Unload Me

    Dim r As Range

    'Get the range from the input box and verify user did not press cancel
    On Error Resume Next
    Set r = GetRange
    On Error GoTo 0
    If r Is Nothing Then Exit Sub   'Pressed cancel so no range is returned, cannot proceed

    'Do what you want with the selected range here
    MsgBox "'" & r.Parent.Name & "'!" & r.Address

End Sub

订阅localStorage change

FB.Event.subscribe('auth.authResponseChange', function(authResponse){
  window.localStorage.setItem('fbstatus',authResponse.status)
});

请注意,storageEvent参数还包含有关可以直接检查的事件的数据,而不是始终在任何存储事件上检查localstorage中的fbstatus值:

window.addEventListener('storage', function(storageEvent){
    // this event will be fired in other tabs (not the originating tab)

    var fbStatus = window.localStorage.getItem('fbstatus');

    // take action based on the status

}, false);