Javascript FB init函数给出错误的版本错误

Javascript FB init函数给出错误的版本错误,javascript,facebook-javascript-sdk,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 // p

我正在使用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,但仍然没有成功。
我做错了什么?

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


我在最近的一个项目中遇到过这个问题。我认为这是一个延迟问题。Facebook SDK要求
出现在页面上。这应该是打开body标记之后的第一件事。在此之后,您可能会看到您的初始化代码

对我来说,这个问题并不一致。我偶尔会看到这只虫子,有时不会。因此,我认为这是一个延迟问题。如果SDK找不到fb根目录,则必须创建一个。在这里,我认为存在延迟问题

尝试在开始的body标记之后,但在
FB.init({})之前添加这个


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

请尝试以下代码:

setInterval(
function() { FB.api('/me/', 
    function(r) { console.log('response: ', r); })
}, 5000);
我注意到当我尝试获取信息时,fb仍然没有初始化

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

FB.getLoginStatus(function(response) { init(); });
存在错误版本:“v2.0”,
这是无效代码

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

对我来说,最有效的方法是删除整个
窗口.fbAsyncInit
函数,并在
sdk.js
的散列中指定
init
属性。例如:

<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>

(功能(d、s、id){
var js,fjs=d.getElementsByTagName[0];
if(d.getElementById(id)){return;}
js=d.createElement;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);
}(文档“脚本”、“facebook jssdk”);
当然,可以省略参数以使用其默认值


我在任何地方都找不到这种方法的文档,因此使用它的风险由您自己承担。幸运的是,我正在将一个较旧的站点从
v1.x
升级到
v2.x
,它在加载
all.js

时使用了这种技术。我通过将脚本加载到document ready而不是document load来解决这个错误

例如,这给出了大约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'));
});
鉴于这一直有效:

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

我们使用自己的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));

    }

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

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

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


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

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

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

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

当我试图在我正在写的一篇文章中嵌入一个简单的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>

每次我重定向到带有fb页面插件的页面(边缘浏览器)时,都会发生错误

如果我刷新页面,它就会工作。如果我通过超链接到达那里,它会抛出错误

通过将
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'));
我换了这个

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

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

工作正常:)

您使用的是cordova-plugin-facebook4插件,这是一条自定义错误消息,表示调用facebook api函数时初始化尚未完成。因为该插件没有使用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. */
var retryFunc=(迭代)=>{
返回新承诺((s,f)=>facebookConnectPlugin.getLoginStatus(s,f))
。然后(身份验证=>authentication.status==='connected')
.然后(isLoggedIn=>{
/*你的代码在这里*/
})
.catch(失败=>{
log(`Waiting for Facebook Init.Iteration:${Iteration | | 0}`);
如果((迭代| | 0)<10){
返回新承诺((s,setTimeout(()=>s(),1000)
.然后(()=>retryFunc(null,(迭代| | 0)+1);
}
else{return Promise.reject({Error:'Failed to check login status',Detail:failure});}
});
};
retryFunc();
/*或者用api调用替换getLoginStatus*/

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


(这是我的问题)

在init之后调用FB api时要当心。init看起来是同步的,但window.fbAsyninit不是,所以你必须等待它的执行。我要复制的示例是在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

这种情况也发生在我身上,前后矛盾很大。我的直觉告诉我,这一定是时间问题。进一步调试,通过手动执行“
FB.login()
”,在开发人员控制台中发现了一个错误。错误是,“init未使用有效版本调用”

在我的例子中,我添加了
//connect.facebook.net/en_US/sdk.js
作为
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
js.src = "https://connect.facebook.net/en_US/sdk.js";
// 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);
}
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'
    });    
  }
}
<!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>
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);
    }

<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
    });
};