Javascript 检测Facebook会话的更改

Javascript 检测Facebook会话的更改,javascript,facebook,facebook-javascript-sdk,Javascript,Facebook,Facebook Javascript Sdk,我网站的外观在很大程度上取决于用户是否通过Facebook登录,因此,我必须在Facebook会话中发现任何变化,以便我调整页面外观以反映用户的登录状态。我讨厌对这类代码使用间隔和超时,因为事情可能会变得非常混乱,但据我所知,这似乎是唯一的选择 我尝试过使用FB.subscribeauth.statusChange,但它似乎没有足够的规律性和必要的正确性。也许我用错了 我测试FB.subscribeauth.statusChange的方法是,每次它被触发时都要记录日志,并在另一个选项卡上有意地登

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

我尝试过使用FB.subscribeauth.statusChange,但它似乎没有足够的规律性和必要的正确性。也许我用错了

我测试FB.subscribeauth.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对象传递给FBAsyninit函数之外的另一个函数是不是一个坏主意?

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

对于大多数情况,您将希望订阅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);

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

对于大多数情况,您将希望订阅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);

我也有同样的问题

我不是一个30秒间歇的超级粉丝,因为我不得不这么做 ping我的服务器以了解我的用户在我的站点中的状态 因为我有facebook用户和普通用户,而且 根据用户的操作,可能没有必要这样做 依赖脸谱网,其他人不依赖

因此,我的目标是只在 用户请求一个实际需要调用Facebook的操作 在服务器端

我将FBJavaScript SDK与PHP SDK结合使用

所以我想我会的

登录:如果已连接,则执行服务器端身份验证 当令牌过期时,我设置了一个超时来执行getStatusLogin 仅刷新令牌 因为auth.statusChange事件似乎只在页面加载时触发 我将根据我的站点中的用户状态在 此时页面加载。 当用户请求需要FB交互->getLoginStatus的操作时 我看到的唯一问题是它会减慢用户响应速度。 您对我每30秒x个用户的服务器负载有何看法

更新

因为最重要的是令牌过期了,所以我将只在调用getLoginStatus的javascript中实现对setTimeout的令牌的自动刷新 对于其余部分,我将坚持使用一个更简单的解决方案,即Facebook异常上的一个不错的服务器错误页面,请求在以下情况下重新连接: 他们在我的应用程序之外注销了facebook, 他们未授权我的应用程序,所以他们无论如何都不想使用它。 在我的例子中,这两种可能性比第一种更具趣闻性。
所以KISS

我也有同样的问题

我不是一个30秒间歇的超级粉丝,因为我不得不这么做 ping我的服务器以了解我的用户在我的站点中的状态 因为我有facebook用户和普通用户,而且 根据用户的操作,可能没有必要这样做 依赖脸谱网,其他人不依赖

所以,我 旨在仅在以下情况下使用javascript执行getLoginStatus 用户请求一个实际需要调用Facebook的操作 在服务器端

我将FBJavaScript SDK与PHP SDK结合使用

所以我想我会的

登录:如果已连接,则执行服务器端身份验证 当令牌过期时,我设置了一个超时来执行getStatusLogin 仅刷新令牌 因为auth.statusChange事件似乎只在页面加载时触发 我将根据我的站点中的用户状态在 此时页面加载。 当用户请求需要FB交互->getLoginStatus的操作时 我看到的唯一问题是它会减慢用户响应速度。 您对我每30秒x个用户的服务器负载有何看法

更新

因为最重要的是令牌过期了,所以我将只在调用getLoginStatus的javascript中实现对setTimeout的令牌的自动刷新 对于其余部分,我将坚持使用一个更简单的解决方案,即Facebook异常上的一个不错的服务器错误页面,请求在以下情况下重新连接: 他们在我的应用程序之外注销了facebook, 他们未授权我的应用程序,所以他们无论如何都不想使用它。 在我的例子中,这两种可能性比第一种更具趣闻性。
因此,KISS

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

订阅auth.authResponseChange并更新localStorage以反映状态:

FB.Event.subscribe('auth.authResponseChange', function(authResponse){
  window.localStorage.setItem('fbstatus',authResponse.status)
});
订阅本地存储更改

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);
请注意,storageEvent参数还包含可直接检查的事件数据,而不是在任何存储事件上始终检查localstorage中的fbstatus值:

storageEvent.key //check if 'fbstatus'
storageEvent.storageArea // the storage object
storageEvent.oldValue
storageEvent.newValue

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

订阅auth.authResponseChange并更新localStorage以反映状态:

FB.Event.subscribe('auth.authResponseChange', function(authResponse){
  window.localStorage.setItem('fbstatus',authResponse.status)
});
订阅本地存储更改

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);
请注意,storageEvent参数还包含可直接检查的事件数据,而不是在任何存储事件上始终检查localstorage中的fbstatus值:

storageEvent.key //check if 'fbstatus'
storageEvent.storageArea // the storage object
storageEvent.oldValue
storageEvent.newValue

谢谢您的回复!:-多久会被解雇一次?即使用户状态更改为“未授权”或“未知”,它是否也会被触发?也许我用错了,但它似乎不起作用。我已将其放入我的代码中,然后在另一个选项卡上注销Facebook。我的站点上绝对没有触发任何事件,控制台中也没有记录任何事件。保留事件订阅有什么意义,因为我将每隔30秒测试一次更改?我想我会使用我建议的第二种方法,使用setTimeout,唯一的问题是我不知道是否应该将Facebook对象传递到另一个函数中。这是个坏主意吗?@BenCarey,在我看来,最好将超时/间隔作为临时解决办法,以防行为发生变化。无论如何,这个事件有时可能会在代码超时/间隔之前触发。好的,多谢多汁,我正在mo工作,到目前为止似乎工作得很好。谢谢你的帮助!谢谢您的回复!:-多久会被解雇一次?即使用户状态更改为“未授权”或“未知”,它是否也会被触发?也许我用错了,但它似乎不起作用。我已将其放入我的代码中,然后在另一个选项卡上注销Facebook。我的站点上绝对没有触发任何事件,控制台中也没有记录任何事件。保留事件订阅有什么意义,因为我将每隔30秒测试一次更改?我想我会使用我建议的第二种方法,使用setTimeout,唯一的问题是我不知道是否应该将Facebook对象传递到另一个函数中。这是个坏主意吗?@BenCarey,在我看来,最好将超时/间隔作为临时解决办法,以防行为发生变化。无论如何,这个事件有时可能会在代码超时/间隔之前触发。好的,多谢多汁,我正在mo工作,到目前为止似乎工作得很好。谢谢你的帮助!这不是问题的答案。请从此内容创建新问题。这不是问题的答案。请从此内容创建一个新问题。