FB.init已经被调用过了。

53

我正在构建Facebook的iframe应用程序。我的应用程序只在加载一次(我只接收signed_request一次),然后我使用内部域链接在iframe中导航到页面。我注意到我在Chrome和Firefox中都看到这些奇怪的消息。

FB.init has already been called - this could indicate a problem

我非常确定这个方法只被调用了一次,而且Facebook希望我每次应用程序加载时都要调用它(而不是每个页面都调用)。

window.fbAsyncInit = function() {
  FB.init({
    appId: param('facebook_app_id'),
    frictionlessRequests: true,
    oauth: true,
    channelUrl: site_url('/channel.html')
  })
}

我在这里犯了什么错误(如果有的话)?


我收到了相同的错误.. 我已经向Facebook提交了一个错误报告: https://developers.facebook.com/bugs/223004254480286 - Roni
请考虑将Tinuo的答案(https://dev59.com/wmkv5IYBdhLWcg3wsC3i#10421328)标记为已接受,顺便提一下,这个bug已经被修复了。 - Roni
我在http://www.permadi.com/tutorial/facebook-js-oauth-popup-centered/index.html运行了Facebook Oauth示例,即使在Firefox控制台中也存在此错误。不知道这个错误是什么意思,但登录和注销过程都可以无缝地进行。 - shasi kanth
3个回答

157

从您将参数传递到js.src中,例如#xfbml=1&appId=X,FB SDK将自动初始化,因此FB.init将尝试重新初始化。

所以在您的代码中,您不必删除FB.init函数,只需确保不在异步加载JS SDK的代码中传递参数即可。

替换为:

js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&appId=X";

使用 :

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

3
如果你想在SDK初始化后立即呈现 xfbml 标签,只需在 FB.init 函数中添加参数 xfbml: true 即可。 - Tinou
3
这是正确的答案,请问楼主能否标记它以帮助未来的用户?这正是我在寻找的。 - Jamie Hartnoll
这绝对是解决方案,截至2013年5月9日仍然有效。Facebook没有明确说明使用额外参数加载将自动初始化。任何已经加载了Facebook JS SDK并复制了Facebook Like按钮源代码的人都应该注意到Like按钮代码中所说的额外参数应该填写...这仅适用于尚未加载SDK的人。 - Rob Evans
3
更新:根据新的文档,您应该将“all.js”替换为“sdk.js”。 - Andres SK
确认。这有助于,按钮仍然可以加载,只需将那些#参数移入FB.init(params)中即可。 - Jacek Pietal
显示剩余6条评论

10
如果你确实需要多次调用init函数,你可以这样做:
FB._initialized = false;
FB.init();

但对我来说毫无意义,我有一个略微不同的问题,但它也与“FB.init has already been called - this could indicate a problem”消息相关。

我有一个基于 AJAX 的网站,在每次页面加载后,我需要从 AJAX 请求中获取的 HTML 渲染 XFBML(评论、点赞按钮和其他内容):

 <div class="fb-comments" data-href="{REMOVED}" data-num-posts="5" data-width="760" colorscheme="dark"></div>

要实现这个功能,您可以在需要渲染XFBML时运行以下代码:

FB.XFBML.parse();

Dmitrij,我每个页面只调用一次init(),但是看起来Facebook希望每个iframe加载只调用一次init(),或者像Pawel所假设的那样自动调用。如果第一种情况是有效的,那么看到代码将会非常有趣。 - potomok

0
我也遇到过这个问题。我只是删除了FB.init({...})部分,然后使用以下代码就可以正常工作了:
window.fbAsyncInit = function () {
    FB.Event.subscribe('auth.logout', function () {
        // subscribe parts
    });

    // here is where fb.init() code was
};
(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/all.js#xfbml=1&appId=X";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));

我猜现在它自动初始化代码了,所以没有必要手动操作。现在我的代码又可以工作了。希望这能有所帮助。


那么,你如何传递 channelUrl 和 frictionlessRequests = true? - potomok
我不需要考虑这个问题,因为我在网站上使用这段代码。但是如果在iframe应用程序中使用可能会有问题。也许可以尝试在js路径后面添加另一个参数“#”?(只是一个想法,我没有测试过)。 - pwkc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接