Обнаружить изменения в сессии Facebook - PullRequest
1 голос
/ 18 марта 2012

Внешний вид моего сайта сильно зависит от того, вошел ли пользователь через 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 ]

2 голосов
/ 18 марта 2012

На самом деле лучше подписаться на auth.authResponseChange событие.Это указано в документации Event.subscribe в качестве передового опыта.

В большинстве случаев вы захотите подписаться на auth.authResponseChange, а не auth.statusChange.Ответ возвращается в виде массива javascript, не закодированного в формате JSON.

Обновление:
Похоже, это также не будет работать для вас, поскольку вызывается из временивремя, если вы делаете вызовы в API Facebook и, возможно, в других случаях, таких как вход / выход из системы.

То, что вы требуете, в действительности не существует в Facebook JS-SDK, и интервалы, по-видимому, являются опцией.Вы можете установить интервал, который будет вызывать только FB.getLoginStatus, и оставить подписки на события как есть, поскольку, если обнаружены изменения статуса / authResponse, события будут запущены.

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

window.setInterval(FB.getLoginStatus, 30000);
1 голос
/ 08 января 2016

Решением, применимым к более современным браузерам, было бы использование событий 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 также содержит данные о событии, которые можно просмотреть напрямую, вместо того, чтобы всегда проверять значение fbstatus в localstorage при любом событии хранения:

storageEvent.key //check if 'fbstatus'
storageEvent.storageArea // the storage object
storageEvent.oldValue
storageEvent.newValue
1 голос
/ 29 сентября 2012

У меня точно такая же проблема.

Я не большой поклонник 30-секундного интервала, так как мне пришлось бы пропинговать свой сервер, чтобы узнать статус моего пользователя на моем сайте, потому чтоУ меня есть пользователи Facebook и обычные пользователи, а также потому, что, возможно, в этом нет необходимости, в зависимости от действий пользователя (действия зависят от facebook, другие нет)

Итак, я собираюсь использовать getLoginStatus в javascript только тогда, когдапользователь запрашивает действие, которое на самом деле должно вызывать Facebook на стороне сервера

Я использую FB Javascript SDK вместе с PHP SDK.

Так что я думаю, что я сделаю

  • в FB.Login: если подключено, выполните проверку подлинности на стороне сервера, и я установил тайм-аут, когда срок действия токена истекает, чтобы выполнить getStatusLogin только для обновления токена
  • Поскольку событие auth.statusChange кажетсязапускать только при загрузке страницы Я буду выполнять действия в зависимости от состояния пользователя на моем сайте в данный момент (загрузка страницы).
  • Когда пользователь запрашивает действие, котороенеобходимо взаимодействие с FB -> getLoginStatus

Единственная проблема, которую я вижу, заключается в том, что это замедлит реакцию пользователяЧто вы думаете о моей озабоченности по поводу нагрузки на мой сервер каждые 30 с x число пользователей?

ОБНОВЛЕНИЕ

  • Поскольку самым раздражающим был токен, срок действия которого истек, ябудет реализовывать только автоматическое обновление благодарности токена setTimeout в javascript, вызывая getLoginStatus
  • В остальном я буду придерживаться более простого решения, которое представляет собой симпатичную страницу с ошибкой сервера в Facebook. Исключение с просьбой переподключиться, если:
    • они вышли из Facebook вне моего приложения,
    • они неавторизовали мое приложение (поэтому они не хотят его использовать в любом случае).

В моем случае эти две возможности гораздо более анекдотичны, чем первая (истечение срока действия токена).так поцелуй

...