FB init函数提供错误的版本错误

时间:2014-06-03 16:07:20

标签: javascript facebook-javascript-sdk

我正在使用Facebook JS sdk,我今天创建了一个新的应用程序。 一切都配置正确。 使用init函数,如:

window.fbAsyncInit = function() {
    FB.init({
      appId      : 'xxxx', // App ID
      status     : false, 
      version:  'v2.0',
      cookie     : true, 
      xfbml      : false  // parse XFBML
    });
};

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

但我有一个错误: "未捕获错误:未使用有效版本调用init" 还尝试了其他版本:2.1,2.2,但仍然没有运气。 我在这里做错了什么?

20 个答案:

答案 0 :(得分:32)

**免责声明 - 这纯粹是猜测。似乎解决了我的问题。


我在最近的一个项目中遇到过这个问题。我认为这是一个延迟问题。 Facebook SDK要求<div id="fb-root"></div>在页面上。这应该是打开body标签后的第一件事。在此之后,您可能会看到初始化代码。

对我来说,这个问题并不一致。我偶尔会看到这个bug,有时我也不会。因此,我的结论是延迟问题。如果SDK无法找到fb-root,则必须创建一个。在这里,我认为存在延迟问题。

尝试在您打开的正文标记之后,但在FB.init({});之前添加此内容。

<div id="fb-root"></div>

这似乎已经解决了我的问题,并希望也能帮助其他人。 v1.0 documentation讨论fb-root的原因,但v2.0文档没有提及该项,可能是因为如果找不到它,init脚本会为你添加它。

答案 1 :(得分:23)

我通过使用all.js而不是sdk.js来实现它。
在您的情况下,它看起来像:

js.src = "//connect.facebook.net/pl_PL/all.js";

而不是

js.src = "//connect.facebook.net/pl_PL/sdk.js";

答案 2 :(得分:11)

&version=v2.0添加到js.src,如下所示:

(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#xfbml=1&version=v2.0";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));

答案 3 :(得分:5)

这个问题困扰了我一段时间。我尝试了这里列出的许多想法,例如更改版本号和移动/删除fb-root

最终对我有用的是删除整个window.fbAsyncInit函数,并在init的散列中指定sdk.js属性。例如:

<script type="text/javascript">
    (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 = "https://connect.facebook.net/en_US/sdk.js#version=v2.2&appId=12345&status=true&cookie=true&xfbml=true";
        fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));
</script>

当然,您可以省略一个参数来使用其默认值。

我无法在任何地方找到此方法,因此请自行承担使用风险。幸运的是,我将旧网站从v1.x升级到v2.x,并在加载all.js时使用了此技术。

答案 4 :(得分:5)

我替换了这个

js.src = "//connect.facebook.net/en_US/sdk.js";

用这个

js.src = "//connect.facebook.net/en_US/all.js";

并且工作:)

答案 5 :(得分:3)

这是唯一可以100%消除错误的修复方法。

您可以通过删除FB.init重新创建此错误。这证实虽然已经加载了sdk.js并且存在FB名称空间,但是当我们尝试在脚本中的其他地方使用FB方法时,FB.init还没有被调用。

因此我们需要确保已调用FB.init。我对此answer采用了类似的方法:

if (typeof(fbApi) === 'undefined') { fbApi = {}; }
fbApi = (function () {

    var 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  : '<?php echo esc_js( $facebook_app_id ); ?>',
        status : true,
        cookie : true,
        xfbml  : true,
        version: 'v2.0'
      });

      fbApiInit = true;
      notifyQ();
    };

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

})();

        (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'));

然后,在其他地方,任何对FB的引用都可以这样做:

        fbApi.ready(function() {
          FB.XFBML.parse($("#fb-comments"));
        });

答案 6 :(得分:3)

这也发生在我身上,并且存在很大的不一致。在某个地方,我的预感说,这是一个时间问题。进一步调试,通过手动执行&#34; FB.login()&#34;在开发者控制台中发现错误。错误说,&#34; init未使用有效版本调用&#34;。

在我的情况下,我在html页面的标题中添加//connect.facebook.net/en_US/sdk.js作为脚本标记,然后window.fbAsyncInit就在另一个文件中。这指出我是一个计时问题,因此我交换了这两个脚本标签。现在,一旦我在window.fbAsyncInit之前加入//connect.facebook.net/en_US/sdk.js,问题便消失了。希望这有助于其他人。

答案 7 :(得分:1)

试试这段代码:

setInterval(
function() { FB.api('/me/', 
    function(r) { console.log('response: ', r); })
}, 5000);

我注意到,当我尝试获取信息时,fb仍未初始化。

我通过将初始化代码添加到以下结尾来修复它:

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

答案 8 :(得分:1)

我通过在文档就绪而不是文档加载上加载脚本来解决此错误。

例如,这给出了大约10%的错误:

$(window).load(function(){
  (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'));
});

虽然这一直有效:

$(window).ready(function(){
  (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'));
});

答案 9 :(得分:1)

对于单页应用程序(以我为例)

在单页应用程序中,您对代码运行顺序的控制较少。有时,脚本会在您调用代码时加载,有时没有。

为使它不管Facebook脚本是否已加载都可以工作,我在运行代码时检查了FB全局变量是否已经定义。如果是这样,我只做一个普通的初始化,否则我提供回调。

这是我的代码:

export function initializeFacebookSdk() {

  /* Asynchronous flow: if the global 'FB' variable is still undefined,
     then the facebook script hasn't loaded yet, in that case, provide
     a global callback that will be called by the facebook code. If the 
     variable is already present, just call the code right away and forget
     about the callback. */
  if(window.FB === undefined) {
    console.log('FB undefined -> provide callback');
    window.fbAsyncInit = function() {
      initialize();
    };
  }
  else {
    console.log('FB defined -> call init right away');
    initialize();
  }

  function initialize() {
    window.FB.init({
      appId      : '492331311256888',
      cookie     : true,
      xfbml      : true,
      version    : 'v3.2'
    });    
  }
}

在我的html文件中,我只提供了facebook提供的脚本,在我的代码中,我可以随时随地调用initializeFacebookSdk()

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>My application</title>
  </head>
  <body>    
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>

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

    <div id="root"></div>
  </body>
</html>

答案 10 :(得分:1)

在初始化后调用FB api时要小心。 Init似乎是同步的,但window.fbAsyncInit不是,所以你必须等待它的执行。我重现的例子是在phonegap浏览器平台上,但在我检查了facebook插件代码后,我确信它也可以在纯javascript环境中重现。

这是我的代码,它会触发错误:

if (window.config.debug_mode) {
    facebookConnectPlugin.browserInit('xxxxxxxxx', function() {
    });
}
// getLoginStatus is wrong here as window.fbAsyncInit is not yet completed
facebookConnectPlugin.getLoginStatus(function(status) {
    alert('logged: ' + JSON.stringify(status));
}, function(error) {
    alert('error: ' + JSON.stringify(error));
});

以下是我修复它的方法:

if (window.config.debug_mode) {
    facebookConnectPlugin.browserInit('xxxxxxxxx', function() {
        facebookConnectPlugin.getLoginStatus(function(status) {
            alert('logged: ' + JSON.stringify(status));
        }, function(error) {
            alert('error: ' + JSON.stringify(error));
        });
    });
}

我确定以下代码会引入浏览器,但我没有时间对其进行验证:

window.fbAsyncInit = function fbAsyncInit () {
    version = version || 'v2.6'

    FB.init({
        appId: appId,
        xfbml: false,
        version: version
    })
}
// now calling any FB function here will rise this error

答案 11 :(得分:0)

在我的情况下,这是一个API版本问题,如错误消息所建议。

让FB脚本标签中加载的版本与FB初始化脚本中的版本匹配,方法是在加载sdk(在散列中)时指定相同的版本,例如版本4.0:

<script src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v4.0"></script>

,并在您的脚本中,例如:

window.fbAsyncInit = function() {
    FB.init({
        appId: XXX,
        autoLogAppEvents: true,
        xfbml: true,
        version: 'v4.0' //<------------- same version
    });
};

答案 12 :(得分:0)

我遇到了同样的问题,我想我找到了根本原因!

根本原因

就我而言,我们正在将FB SDK动态注入到客户的网站。但是,我们的一些客户已经通过其他插件添加了FB SDK。这些插件具有不同的应用ID和版本。

因此,根据延迟情况,某些插件会在我们之前/之后调用init

解决方案

如果您是要注入SDK的网站的所有者,请确保没有其他插件正在注入FB SDK并调用init不同的版本和应用ID

如果您不是网站的所有者,则至少尝试先将SDK注入他人,然后选择not async

我也向FB报告了同样的情况。他们告诉不要单独调用init,直接在规则中传递init参数。我已经附上了我使用的代码:

if (!document.getElementById("fb-root")) {
      // create div required for fb
      const fbDiv = document.createElement("div");
      fbDiv.id = "fb-root";
      document.body.appendChild(fbDiv);
      // Run any script after sdk is loaded
      window.fbAsyncInit = () => {
        //
      };
      // inject sdk.js
      (function(d, script) {
        script = d.createElement("script");
        script.type = "text/javascript";
        script.async = true;
        script.src =
          "https://connect.facebook.net/en_GB/sdk.js#xfbml=1&version=v3.2&appId=" +
          process.env.REACT_APP_FB_APP_ID +
          "&autoLogAppEvents=1";
        d.getElementsByTagName("head")[0].appendChild(script);
      })(document);
    }

答案 13 :(得分:0)

确保您在网址

中使用https://
js.src = "https://connect.facebook.net/en_US/sdk.js";

我也不会相信这一点,但Facebook在他们当前的示例代码和我所拥有的内容之间的唯一区别是https://而不是//作为网址。

更新为https://似乎为我修复了它,我无法复制错误。

此外,如果您在代码中的其他位置进行任何检查,以确定是否定义了FB,请务必选中if (window.FB)而不是if (FB),否则您将收到错误。

// call after manually adding DOM nodes containing FB widgets
if (window.FB)
{
    window.FB.XFBML.parse()
}

如果您正在使用打字稿,则需要添加以下内容:

interface Window
{
    FB: IFacebook;
}

interface IFacebook
{
    XFBML: any;
    ui: any;
    getLoginStatus(callback: (response: { status: string }) => any);
    login(callback: (response) => any, options: any);
    logout(callback: () => any);
    Event: any;
    api(url: string, callback: (response: any) => any);
}

答案 14 :(得分:0)

单一包含 - 确保Facebook JavaScript API不会在您的页面上多次包含。

(这是我的问题)

答案 15 :(得分:0)

您正在使用cordova-plugin-facebook4插件,这是一个自定义错误消息,表示在调用facebook api函数时init尚未完成。由于插件没有使用setTimeout给出waitForInitialize,然后重试api方法是最好的选择。

var retryFunc = (iteration) => {
    return new Promise((s, f) => facebookConnectPlugin.getLoginStatus(s, f))
    .then(authentication => authentication.status === 'connected')
    .then(isLoggedIn => {
        /* Your Code Here */
    })
    .catch(failure => {
        console.log(`Waiting for Facebook Init. Iteration: ${iteration || 0}`);
        if((iteration || 0) < 10) { 
            return new Promise((s, setTimeout(() => s(), 1000)
            .then(() => retryFunc(null, (iteration || 0) + 1);
        }
        else { return Promise.reject({Error: 'Failed to check login status.', Detail: failure}); }
    });
};

retryFunc();
/* Or replace getLoginStatus with your api call. */

答案 16 :(得分:0)

每次重定向到具有fb-page插件的页面(Edge Browser)时都会发生错误。

如果我刷新页面就行了。如果我通过超链接到达那里就会抛出错误。

通过向脚本添加sdk.js?d=" + new Date().toISOString();来修复它。

(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?d=" + new Date().toISOString();
        fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));

答案 17 :(得分:0)

当我试图在我写的一篇文章中嵌入一个简单的Facebook帖子时,我遇到了同样的问题。

<div id="fb-root"></div><script>(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#xfbml=1&amp;version=v2.3";  fjs.parentNode.insertBefore(js, fjs);}(document, 'script', 'facebook-jssdk'));</script><div class="fb-post" data-href="https://www.facebook.com/feyenoord/posts/10153224326681816:0" data-width="500"><div class="fb-xfbml-parse-ignore"><blockquote cite="https://www.facebook.com/feyenoord/posts/10153224326681816:0"><p>Een teleurstellende middag in De Kuip. Ook ADO Den Haag bleek vanmiddag te sterk voor Feyenoord. http://bit.ly/1UA3ZxZADO Den Haag too strong for Feyenoord. http://bit.ly/1UA6rEN</p>Posted by <a href="https://www.facebook.com/feyenoord/">Feyenoord Rotterdam</a> on&nbsp;<a href="https://www.facebook.com/feyenoord/posts/10153224326681816:0">Sunday, January 31, 2016</a></blockquote></div></div>

当我调试Facebook sdk.js时,我看到.getVersion返回&#34;未定义&#34;因此不会渲染小部件。

显然,在加载&amp;时,Facebook无法处理由&而非sdk.js分隔的传递查询参数。出于验证原因,我已将代码更改为&amp;

Works:        js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.3";
Doesn't Work: js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&amp;version=v2.3";

Facebook sdk debug getVersion

答案 18 :(得分:0)

我们使用自己的API执行此操作:

   _loadFacebookApi: function(callback) {
        logger.info('_loadFacebookApi');

        (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 = "https://connect.facebook.net/en_US/sdk.js";


        }(document, 'script', 'facebook-jssdk'));

        var fbScript = window.document.getElementById('facebook-jssdk');

        fbScript.onload = fbScript.onreadystatechange = (function() {

            logger.info('fbScript onLoad');

            window.FB.init({
                version: 'v2.1',
                appId: '',
                channelUrl: '/fbchannel.html',
                status: false,
                cookie: true,
                xfbml: true,
                logging: true,
                oath: true
            });

            this.dispatch(constants.FACEBOOK_INIT_SUCCESS);

            if(callback){
                callback();
            }

        }.bind(this));

    }

答案 19 :(得分:-3)

window.fbAsyncInit = function() {
    FB.init({
      appId      : 'xxxx', // App ID
      status     : false, 
      version:  'v2.0',
      cookie     : true, 
      xfbml      : false  // parse XFBML
    });
};

错误版本:&#39; v2.0&#39;, 这不是有效的代码