admin管理员组

文章数量:1389783

In order to make calls on the Facebook Graph Api, users have to log in and accept my application on my website. With Ghostery enabled and Facebook Connect blocked, it just fails to load the sdk and I get a nice GET .js net::ERR_BLOCKED_BY_CLIENT in my Chrome console. Obviously it breaks the feature.

Is there a nice and simple client side way of detecting Ghostery's blockings so I can display a friendly message instead, asking the user to whitelist my website if he wants a full access to the features ?

FYI, I'm using Angularjs and use a provider to load the sdk and make the calls. This is how it looks :

function fbInit(appID) {

    (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/en_US/sdk.js";
        fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk')); 

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

this.setAppID = function(appID) {
    this.appID = appID;
};

this.$get = function() {
    var appID = this.appID;
    var self = this;
    fbInit(appID);

    return {
        /* Methods */
    };
};

In order to make calls on the Facebook Graph Api, users have to log in and accept my application on my website. With Ghostery enabled and Facebook Connect blocked, it just fails to load the sdk and I get a nice GET http://connect.facebook/en_US/sdk.js net::ERR_BLOCKED_BY_CLIENT in my Chrome console. Obviously it breaks the feature.

Is there a nice and simple client side way of detecting Ghostery's blockings so I can display a friendly message instead, asking the user to whitelist my website if he wants a full access to the features ?

FYI, I'm using Angularjs and use a provider to load the sdk and make the calls. This is how it looks :

function fbInit(appID) {

    (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/en_US/sdk.js";
        fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk')); 

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

this.setAppID = function(appID) {
    this.appID = appID;
};

this.$get = function() {
    var appID = this.appID;
    var self = this;
    fbInit(appID);

    return {
        /* Methods */
    };
};
Share Improve this question asked Oct 22, 2014 at 9:14 deonclemdeonclem 88011 silver badges25 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 5

Facebook calls fbAsyncInit when the JS client has been loaded. If that function hasn't been run after a certain amount of time you can be relatively sure it has failed. One approach you could take is something like this.

window.fbLoaded = false;

setTimeout(function() {
    if (!fbLoaded) {
        // show error
    }
}, 5 * 1000);

window.fbAsyncInit = function() {
    window.fbLoaded = true;
    // hide error incase client took more than 5 seconds to load
    // continue running your code as usual
}

You can try to load the file yourself via XHR before initializing FB API, and abort/inform the user upon error with that request.

I assume you already have host permissions for connect.facebook

In 2019 except anti-tracking browser extensions, some browsers' default behaviour is to block third party tracking cookies (e.g. firefox and maybe more) so I used @Xan's approach for my case for my Angular (2+) project. I am using Fetch API to check for allowance. (You can check for browser patibility of Fetch API in the link provided). Below you call checkIfFacebookIsBlocked() function as soon as possible in your app's initialization or after GDPR acceptance etc.

  checkIfFacebookIsBlocked() {
    const _this = this;
    fetch('https://connect.facebook/en_US/sdk.js')
      .then(function() {
        console.log('Facebook sdk is allowed:');
        _this.initFacebookSdk();
      })
      .catch(function() {
        console.log('Facebook sdk is NOT allowed:');
        // handle the case that facebook is not allowed
      });
  }


  initFacebookSdk() {
    const _this = this;
    (window as any).fbAsyncInit = function() {
      FB.init({
        appId      : FACEBOOK_APP_ID, // fb App ID
        cookie     : true,
        xfbml      : true,
        version    : FACEBOOK_SDK_VERSION // fb app's api version
      });
      FB.AppEvents.logPageView();
      // your code after Facebook sdk is loaded... (getLoginStatus(), login(), api('/me', ...) etc.)
    };
    (function(d, s, id) {
      let js;
      const fjs = d.getElementsByTagName(s)[0];
      if (d.getElementById(id)) { return; }
      js = d.createElement(s); js.id = id;
      js.src = 'https://connect.facebook/en_US/sdk.js';
      fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));
  }

You can attach an onerror handler to the script tag that loads the API that will trigger when the API request fails.

This can be much faster than setting a timeout and waiting on fbAsyncInit

本文标签: javascriptFacebook Sdk blockedHow to detect if a user is using GhosteryStack Overflow