简体   繁体   中英

FB.api only loads on first AJAX call to page

I have an issue with an FB.api only loading the first time a page is retrieved via AJAX. FB.getLoginStatus does work though.

Demo page: http://proof.ptly.com/test/fb/test-ajax.htm (clicking the load link works the first time but fails the second time it is clicked)

Expected/Desired behaviour : after giving permission to the app, it should list of all groups or pages associated to the user

Current behaviour : group list is only populated on first load. subsequent clicks do not load the list (FB.api does not return a response - view console for logging)

The reason behind this problem is that the page I am retrieving (test.htm) can't be changed but the page I am calling it from (test-ajax.htm) can. While I know this method isn't pretty nor ideal, I'm wondering if it is possible to overcome. Thus suggestions to change the underlying test.htm, while correct, won't solve the problem I'm having.

Sample code

Main page that calls the AJAX page

<html>
    <head>
        <title>My Facebook Login Page</title>
        <script type="text/javascript" language="javascript" src="js/jquery.js"></script>
        <script>
        var loaded = false;
        jQuery(document).ready(function(){
            jQuery("#lnk").click(function(e){
                e.preventDefault();
                jQuery("#divContent").load("test.htm", function(){
                    if(loaded)
                    {

                        FB.getLoginStatus(FBverifyLogin);
                    }
                    else
                    {

                        loaded = true;
                    }
                });
            });
        });
        </script>
    </head>
    <body>
        <a href="#" id='lnk'>load</a>
        <div id='divContent'></div>
    </body>
 </html>

AJAX page being retrieved

    <script type="text/javascript">
        var FB_config = {
            API_ID: "347798778614308",
            PERMISSIONS: "publish_stream,manage_pages,user_groups",
        };
        (function(d){
           var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
           js = d.createElement('script'); js.id = id; js.async = true;
           js.src = "//connect.facebook.net/en_US/all.js";
           d.getElementsByTagName('head')[0].appendChild(js);
         }(document));


        jQuery(document).ready(function(){
            // initialise FB
            window.fbAsyncInit = function() {
                FB.init({
                    appId      : '347798778614308',
                    status     : true, 
                    cookie     : true,
                    xfbml      : true,
                    oauth      : true
                });
                FB.Event.subscribe('auth.statusChange', FBverifyLogin);
            };
        });


        function FBverifyLogin(response) {
            console.log("FBverifyLogin");
            console.log(response);
            jQuery("#FBreauth").hide();
            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
                var uid = response.authResponse.userID;
                var accessToken = response.authResponse.accessToken;
                ShowPostToFacebookCheckbox();
                FBdisplayMyPages(response.authResponse);
                jQuery("#btnLogin").hide();
                checkPermissions();

            } else if (response.status === 'not_authorized') {

            } else {
                // the user isn't logged in to Facebook.
                jQuery("#btnLogin").show();
                return false;
            }
        }
        function checkPermissions(){
            console.log("checkPermissions");
            FB.api('/me/permissions', function(response) {
                console.log("in checkPermissions fb.api");
                console.log(response);
                var permissions = FB_config.PERMISSIONS.split(",");
                for(var i = 0; i < permissions.length; i++)
                {
                    if(response.data[0][permissions[i]] == undefined || response.data[0][permissions[i]] != 1)
                    {
                        jQuery("#FBreauth").show();
                        break;
                    }
                }
            });
        }
        function FBdisplayMyPages(authResponse){
            console.log("FBdisplayMyPages");
            console.log(authResponse);
            FB.api('/me/accounts', function(response) {
                console.log("in FBdisplayMyPages fb.api");
                console.log(response);
                var str = "";
                var name = "";
                var count = 0;
                str += '<optgroup label="Pages">';
                for(var i = 0; i < response.data.length; i++)
                {
                    if(response.data[i].category != "Application")
                    {
                        name = response.data[i].name;
                        str += '<option value="'+response.data[i].id+"_"+response.data[i].access_token+'">'+name+'</option>';
                        count++;
                    }
                }
                str += "</optgroup>";

                jQuery("#msgPostOn").html(str);
                FB.api('/me/groups', function(response) {
                    console.log("in FBdisplayMyPages fb.api 2");
                    console.log(response);

                    str = jQuery("#msgPostOn").html();
                    str += '<optgroup label="Groups">';
                    name = "";

                    for(var i = 0; i < response.data.length; i++)
                    {
                        if(response.data[i].category != "Application")
                        {
                            name = response.data[i].name;
                            str += '<option value="'+response.data[i].id+"_"+authResponse.accessToken+'">'+name+'</option>';
                            count++;

                        }
                    }
                    str += "</optgroup>";
                    jQuery("#msgPostOn").html(str);

                    switch(count)
                    {
                        case 0:
                            // notify that there are not pages. will post to personal page
                            str += '<option value="' + authResponse.userID + "_" + authResponse.accessToken + '">Personal Account</option>';
                            jQuery("#msgPostOn").html(str);
                            jQuery("#FBpostTo").text("No pages found. Posting to your personal account");
                            jQuery("#FBpostTo").show();

                            break;
                        case 1:
                            // only 1 page. hide it...
                            // notify name of page to update

                            jQuery("#msgPostOn").hide();
                            jQuery("#FBpostTo").html("Posting to <strong>" + name + "</strong>");
                            jQuery("#FBpostTo").show();
                            break;
                        default:
                            // notify user to select a page to post to
                            jQuery("#FBpostTo").text("There are multiple groups/pages associated with your account. Specify which to post to ");
                            jQuery("#FBpostTo").show();
                            jQuery("#msgPostOn").show();
                    }
                });
            });
        }
        function FBrefresh(){
            console.log("FBrefresh");
            FB.getLoginStatus(FBverifyLogin);
        }
        function FBreauth(){
            console.log("FBreauth");
            FB.ui(
                {
                    method: 'oauth',
                    display: 'popup',

                    app_id: FB_config.API_ID,
                    client_id: FB_config.API_ID,
                    redirect_uri: "http://www.facebook.com/connect/login_success.html",

                    scope: FB_config.PERMISSIONS
                }
            );          
        }

        function ShowPostToFacebookCheckbox() 
        { 
            console.log("ShowPostToFacebookCheckbox");
            jQuery('#postToFacebook2').css('display', 'inline'); 
            jQuery('#LabelForFacebook').css('display', 'inline'); 
        }

    </script>       

    <div id="fb-root"></div>
<div id="postToFacebookField" class="fieldContainer checkbox ">
    <div id="btnLogin" class="fb-login-button" scope="publish_stream,manage_pages,user_groups">Login with Facebook</div>
    <input type="checkbox" style="display:none" name="postToFacebook2" value="on" id="postToFacebook2"> 
    <label style="cursor: pointer; display:none" for="postToFacebook2" id="LabelForFacebook">Post to Facebook Page</label>
    <div id="FBpostTo" style="display: none"></div>
    <select id="msgPostOn" style="display: none"></select>
    <div style="display: none" id="FBreauth">(Insufficient permissions. <a href ='#' onclick='FBreauth(); return false;'>Authorize this app</a> and <a href='#' onclick='FBrefresh() ; return false'>refreshing</a>)</div>
</div>

If you are still looking for a solution to this problem, I believe I have something that might work within the constraints that you have set. Quite simply, we just clear all the loaded variables and objects in memory, and from my tests, including the <script> that facebook attaches.

Replace the click handler in test.htm with this and it should work

jQuery(document).ready(function(){
    jQuery("#lnk").click(function(e){
        if(FB && document.getElementById("facebook-jssdk")){ //if set, reset
              //removes the <script>
          document.head.removeChild(document.getElementById("facebook-jssdk")); 
          window.FB=null; //unloads the APIs
          loaded=null; 
        }
        e.preventDefault();
        jQuery("#divContent").load("test.htm", function(){
            if(loaded)
            {
                FB.getLoginStatus(FBverifyLogin);
            }
            else
            {   
                loaded = true;
            }
        });
    });
});

We had a similar kind of issue, this post http://www.martincarlin.info/facebook-js-sdk-not-working-on-second-load-of-ajax-loaded-page/ helped us to resolve the issue.

The reason the script was not working was because the window.fbAsyncInit function runs on the initial page load and so the second time you do your AJAX call, the Facebook JavaScript SDK is already loaded in your page so window.fbAsyncInit doesn't fire again.

By checking if FB is already defined we can then use our SDK code without the initialisation part.

Hope that will help you to resolve the issue.

After trying everything from past few days this below piece of code worked for me.

//intialize FB object (this is useful if you are using Turbolinks)
$(document).on('page:load', function(){
 intializeFB();
});

intializeFB();

function intializeFB(){
 if(typeof(FB) !== "undefined"){
  delete FB;
 }
 $.getScript("http://connect.facebook.net/en_US/all.js#xfbml=1",      function () {
   FB.init({
     appId      : '19871816653254',
     cookie     : true,  // enable cookies to allow the server to access 
                         // the session
     xfbml      : true,  // parse social plugins on this page
     oauth      : true,
     status     : true,
     version    : 'v2.4' // use version 2.4
   });
 });
}

Hope this is useful!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM