Facebook의 FB.init가 완료되면 감지하는 방법


115

이전 JS SDK에는 FB.ensureInit라는 함수가있었습니다. 새 SDK에는 이러한 기능이없는 것 같습니다. 완전히 시작될 때까지 API 호출을하지 않으려면 어떻게해야합니까?

나는 모든 페이지의 상단에 이것을 포함합니다 :

<div id="fb-root"></div>
<script>
  window.fbAsyncInit = function() {
    FB.init({
      appId  : '<?php echo $conf['fb']['appid']; ?>',
      status : true, // check login status
      cookie : true, // enable cookies to allow the server to access the session
      xfbml  : true  // parse XFBML
    });
    FB.Canvas.setAutoResize();
  };

  (function() {
    var e = document.createElement('script');
    e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
    e.async = true;
    document.getElementById('fb-root').appendChild(e);
  }());
</script>

이 문제에 대한 내 솔루션은이 링크를 참조하십시오. facebook.stackoverflow.com/questions/12399428/…
Remi Grumeau 2013

답변:


138

2012 년 1 월 4 일 업데이트

방금 (예 : FB-의존하는 방법을 호출 할 수 없습니다 것 같다 FB.getAuthResponse()직후) FB.init()전 등이 아니라, FB.init()지금 비동기 것 같다. 코드를 FB.getLoginStatus()응답 으로 래핑 하면 API가 완전히 준비되었을 때 감지하는 트릭을 수행하는 것 같습니다.

window.fbAsyncInit = function() {
    FB.init({
        //...
    });

    FB.getLoginStatus(function(response){
        runFbInitCriticalCode(); 
    });

};  

또는 fbEnsureInit()아래에서 구현을 사용 하는 경우 :

window.fbAsyncInit = function() {
    FB.init({
        //...
    });

    FB.getLoginStatus(function(response){
        fbApiInit = true;
    });

};  

원본 게시물 :

FB가 초기화 될 때 스크립트를 실행하려면 내부에 콜백 함수를 넣을 수 있습니다 fbAsyncInit.

  window.fbAsyncInit = function() {
    FB.init({
      appId  : '<?php echo $conf['fb']['appid']; ?>',
      status : true, // check login status
      cookie : true, // enable cookies to allow the server to access the session
      xfbml  : true  // parse XFBML
    });
    FB.Canvas.setAutoResize();

    runFbInitCriticalCode(); //function that contains FB init critical code
  };

FB.ensureInit의 정확한 교체를 원한다면 공식적인 교체가 없기 때문에 직접 작성해야합니다 (큰 실수 imo). 내가 사용하는 것은 다음과 같습니다.

  window.fbAsyncInit = function() {
    FB.init({
      appId  : '<?php echo $conf['fb']['appid']; ?>',
      status : true, // check login status
      cookie : true, // enable cookies to allow the server to access the session
      xfbml  : true  // parse XFBML
    });
    FB.Canvas.setAutoResize();

    fbApiInit = true; //init flag
  };

  function fbEnsureInit(callback) {
        if(!window.fbApiInit) {
            setTimeout(function() {fbEnsureInit(callback);}, 50);
        } else {
            if(callback) {
                callback();
            }
        }
    }

용법:

fbEnsureInit(function() {
    console.log("this will be run once FB is initialized");
});

2
감사합니다 Serg .. 당신은 전설입니다!
Pablo

3
FB.init가 호출 된 직후에 Facebook API 요청을 실행할 수 없습니다. 아마도 사용중인 메서드가 'fql.query'이기 때문일까요? 어느 쪽이든 fbApiInit 플래그에 긴 시간 제한을 설정해야합니다.
Ian Hunter

업데이트 해 주셔서 감사합니다. 동일한 문제가 발생했으며 업데이트 된 솔루션이 완벽하게 작동했습니다!
Terri Ann

@beanland, fql.query api 호출은 사용자가 로그인해야합니다.에서 response다시받은 후 쿼리를 실행하고 FB.getLoginStatus(function(response){}있습니까? -위의 "업데이트 된 답변"과 "원래 답변"의 차이점에 유의하십시오.
tjmehta 2012

@serg 예를 들어 주셔서 감사합니다. fbAsyncInit로드 후 호출되도록 함수 내부 에 지연을 넣어야했습니다window.fbAsyncInit = function() { FB.init({ appId : '*************', channelUrl : 'http://www.mydomain.com', status : true, // check login status cookie : true, // enable cookies to allow the server to access the session oauth : true, // enable OAuth 2.0 xfbml : true // parse XFBML }); setTimeout(function() { myfunction(function (callback) {}, '', '', '' ); }, 1200); };
tq

38

실제로 Facebook은 이미 인증 이벤트를 구독하는 메커니즘을 제공했습니다.

귀하의 경우 " status : true "를 사용하고 있습니다. 이는 FB 객체가 사용자의 로그인 상태를 Facebook에 요청한다는 것을 의미합니다.

FB.init({
    appId  : '<?php echo $conf['fb']['appid']; ?>',
    status : true, // check login status
    cookie : true, // enable cookies to allow the server to access the session
    xfbml  : true  // parse XFBML
});

"FB.getLoginStatus ()"를 호출하면 동일한 요청을 다시 실행하게 됩니다 .

대신 FB.init 를 호출하기 전에 FB.Event.subscribe 를 사용 하여 auth.statusChange 또는 auth.authResponseChange 이벤트 를 구독 할 수 있습니다.

FB.Event.subscribe('auth.statusChange', function(response) {
    if(response.status == 'connected') {
        runFbInitCriticalCode();
    }
});

FB.init({
    appId  : '<?php echo $conf['fb']['appid']; ?>',
    status : true, // check login status
    cookie : true, // enable cookies to allow the server to access the session
    xfbml  : true  // parse XFBML
});

대부분의 경우 " status : false "를 사용할 때 비동기 호출이 없기 때문에 FB.init 직후에 모든 코드를 실행할 수 있습니다.


참고 :이 방법을 사용할 경우 유일한주의 사항은 로그인하지 않은 경우 이벤트가 트리거되지 않는다는 것입니다. 기본 UI 상태를 인증되지 않은 것처럼 설정하면 완벽하게 작동합니다. 그런 다음 이벤트 처리기 내에서 connected 또는 not_authorized를 확인할 수 있습니다.
David C

또한, 프런트 엔드 응용 프로그램에 대한 사용자 로그인 새로 고침 사이의 상태, 설정을 유지하기 cookietrue초기화 PARAM 객체한다.
MK Safi

12

다음은 사용하는 경우의 해결책입니다. 및 Facebook 비동기 지연로드 :

// listen to an Event
$(document).bind('fbInit',function(){
    console.log('fbInit complete; FB Object is Available');
});

// FB Async
window.fbAsyncInit = function() {
    FB.init({appId: 'app_id', 
         status: true, 
         cookie: true,
         oauth:true,
         xfbml: true});

    $(document).trigger('fbInit'); // trigger event
};

3
나는 그것을 사랑한다! 유일한 문제는 Facebook이 여는 <body> 태그 바로 뒤에 FB 초기화 코드를 포함해야한다고 주장하고, 가장 좋은 방법은 닫는 <body> 태그 전에 jQuery를로드해야한다는 것입니다. 도! 닭고기와 계란. 나는 "screw you, Facebook"이라고 말하고 jQuery 후에 FB를로드하고 싶다.
Ethan Brown

@EthanBrown 동의합니다-귀하의 페이지에는 FB가 필요한 것보다 jQuery가 더 많이 필요하므로 이해가됩니다. 몇 년 전 페이지 끝에 jQuery로드 시도를 포기했습니다 ;-)
Simon_Weaver

추가 version: 'v2.5'초기화 JSON 다른 하나는 지혜가없는 일 .. 잎에서 나를 위해하지 않았다 것입니다. 도움을 주셔서 감사합니다
카스 반살

10

FB가 초기화되었는지 확인하는 또 다른 방법은 다음 코드를 사용하는 것입니다.

ns.FBInitialized = function () {
    return typeof (FB) != 'undefined' && window.fbAsyncInit.hasRun;
};

따라서 페이지 준비 이벤트에서 ns.FBInitialized를 확인하고 setTimeOut을 사용하여 이벤트를 이후 단계로 연기 할 수 있습니다.


이것은 진짜입니다! 감사!
티아고 마세도

이것은 간단한 것입니다. 그것은처럼
패리스 Rayhan

5

위의 솔루션 중 일부가 작동하는 동안 FB가 초기화되고 사용할 준비가되는 즉시 실행되는 '준비'메서드를 정의하는 최종 솔루션을 게시 할 것이라고 생각했습니다. FB가 준비되기 전이나 후에 호출하는 것이 안전하다는 다른 솔루션에 비해 장점이 있습니다.

다음과 같이 사용할 수 있습니다.

f52.fb.ready(function() {
    // safe to use FB here
});

다음은 소스 파일입니다 ( 'f52.fb'네임 스페이스 내에 정의되어 있음).

if (typeof(f52) === 'undefined') { f52 = {}; }
f52.fb = (function () {

    var fbAppId = f52.inputs.base.fbAppId,
        fbApiInit = false;

    var awaitingReady = [];

    var notifyQ = function() {
        var i = 0,
            l = awaitingReady.length;
        for(i = 0; i < l; i++) {
            awaitingReady[i]();
        }
    };

    var ready = function(cb) {
        if (fbApiInit) {
            cb();
        } else {
            awaitingReady.push(cb);
        }
    };

    window.fbAsyncInit = function() {
        FB.init({
            appId: fbAppId,
            xfbml: true,
            version: 'v2.0'
        });

        FB.getLoginStatus(function(response){
            fbApiInit = true;
            notifyQ();
        });
    };

    return {
        /**
         * Fires callback when FB is initialized and ready for api calls.
         */
        'ready': ready
    };

})();

4

전역 함수를 사용하여 setTimeout 사용을 피했습니다.

참고 편집 : 다음 도우미 스크립트를 업데이트하고 사용하기 더 쉽고 간단한 클래스를 만들었습니다. 여기에서 확인하세요 ::: https://github.com/tjmehta/fbExec.js

window.fbAsyncInit = function() {
    FB.init({
        //...
    });
    window.fbApiInit = true; //init flag
    if(window.thisFunctionIsCalledAfterFbInit)
        window.thisFunctionIsCalledAfterFbInit();
};

fbEnsureInit는 FB.init 이후에 콜백을 호출합니다.

function fbEnsureInit(callback){
  if(!window.fbApiInit) {
    window.thisFunctionIsCalledAfterFbInit = callback; //find this in index.html
  }
  else{
    callback();
  }
}

fbEnsureInitAndLoginStatus는 FB.init 이후 및 FB.getLoginStatus 이후에 콜백을 호출합니다.

function fbEnsureInitAndLoginStatus(callback){
  runAfterFbInit(function(){
    FB.getLoginStatus(function(response){
      if (response.status === 'connected') {
        // the user is logged in and has authenticated your
        // app, and response.authResponse supplies
        // the user's ID, a valid access token, a signed
        // request, and the time the access token
        // and signed request each expire
        callback();

      } else if (response.status === 'not_authorized') {
        // the user is logged in to Facebook,
        // but has not authenticated your app

      } else {
        // the user isn't logged in to Facebook.

      }
    });
  });
}

fbEnsureInit 예제 사용 :

(FB.login은 FB가 초기화 된 후 실행되어야합니다.)

fbEnsureInit(function(){
    FB.login(
       //..enter code here
    );
});

fbEnsureInitAndLogin 예제 사용 :

(FB.api는 FB.init 후 실행해야하며 FB 사용자는 로그인해야합니다.)

fbEnsureInitAndLoginStatus(function(){
    FB.api(
       //..enter code here
    );
});

1
위와 같은 작업을 더 쉽고 깔끔하게 수행하는이 도우미 클래스를 작성했습니다. 여기에 체크 아웃 : github.com/tjmehta/fbExec.js을
tjmehta

4

setTimeout 또는 setInterval을 사용하는 대신 지연된 객체를 사용합니다 ( 여기 에서 jQuery에 의한 구현 ). init에는 콜백이 없지만 결과를 이벤트 구독과 결합하면 (누군가가 나에게 지적했듯이) 적절한 순간에 대기열을 해결하는 것이 여전히 까다 롭습니다.

의사 스 니펫은 다음과 같습니다.

FB.Event.subscribe('auth.statusChange', function(response) {
   if (response.authResponse) {
       // user has auth'd your app and is logged into Facebook
   } else {
       // user has not auth'd your app, or is not logged into Facebook
   }
   DeferredObject.resolve();
});

4

이벤트 나 시간 제한이 필요없는 더 간단한 방법이 있습니다. 그러나 jQuery가 필요합니다.

사용 jQuery.holdReady() (문서)

따라서 jQuery 스크립트 직후에 ready 이벤트를 지연하십시오.

<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
    $.holdReady( true ); // don't fire ready until told (ie when FB loaded)
</script>

그런 다음 Facebook init 함수에서 해제합니다.

window.fbAsyncInit = function() {
    FB.init({
        appId: '11111111111111',
        cookie: true,
        xfbml: false,
        version: 'v2.4'
    });

    // release the ready event to execute
    $.holdReady( false );
};

그런 다음 준비 이벤트를 정상적으로 사용할 수 있습니다.

$(document).ready( myApp.init );

2

이벤트를 구독 할 수 있습니다.

즉)

FB.Event.subscribe('auth.login', function(response) {
  FB.api('/me', function(response) {
    alert(response.name);
  });
});

2

작지만 중요한 알림 :

  1. FB.getLoginStatus이후 FB.init에 호출해야합니다 . 그렇지 않으면 이벤트가 발생하지 않습니다.

  2. 을 사용할 수 FB.Event.subscribe('auth.statusChange', callback)있지만 사용자가 facebook에 로그인하지 않으면 실행되지 않습니다.

다음은 두 기능을 사용한 작업 예입니다.

window.fbAsyncInit = function() {
    FB.Event.subscribe('auth.statusChange', function(response) {
        console.log( "FB.Event.subscribe auth.statusChange" );
        console.log( response );
    });

    FB.init({
        appId   : "YOUR APP KEY HERE",
        cookie  : true,  // enable cookies to allow the server to access
                // the session
        xfbml   : true,  // parse social plugins on this page
        version : 'v2.1', // use version 2.1
        status  : true
    });

    FB.getLoginStatus(function(response){
        console.log( "FB.getLoginStatus" );
        console.log( response );
    });

};

// Load the SDK asynchronously
(function(d, s, id) {
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s); js.id = id;
    js.src = "//connect.facebook.net/en_US/sdk.js";
    fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));

1

Facebook API는 FB._apiKey를 감시하므로 다음과 같은 API 애플리케이션을 호출하기 전에이를 감시 할 수 있습니다.

window.fbAsyncInit = function() {
  FB.init({
    //...your init object
  });
  function myUseOfFB(){
    //...your FB API calls
  };
  function FBreadyState(){
    if(FB._apiKey) return myUseOfFB();
    setTimeout(FBreadyState, 100); // adjust time as-desired
  };
  FBreadyState();
}; 

이것이 차이를 만드는지 확실하지 않지만 제 경우에는 UI가 준비되었는지 확인하고 싶었 기 때문에 jQuery의 문서 준비 (위의 마지막 부분)로 초기화를 래핑했습니다.

  $(document).ready(FBreadyState);

또한 Facebook의 all.js를로드하는 데 async = true를 사용하지 않습니다. 제 경우에는 UI에 로그인하고 기능을보다 안정적으로 구동하는 데 도움이되는 것 같습니다.


1

때때로 fbAsyncInit가 작동하지 않습니다. 이유를 모르고 다음 해결 방법을 사용합니다.

 var interval = window.setInterval(function(){
    if(typeof FB != 'undefined'){
        FB.init({
            appId      : 'your ID',
            cookie     : true,  // enable cookies to allow the server to access// the session
            xfbml      : true,  // parse social plugins on this page
            version    : 'v2.3' // use version 2.3
        });

        FB.getLoginStatus(function(response) {
            statusChangeCallback(response);
        });
        clearInterval(interval);
    }
},100);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.