我正在使用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,但仍然没有运气。 我在这里做错了什么?
答案 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&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 <a href="https://www.facebook.com/feyenoord/posts/10153224326681816:0">Sunday, January 31, 2016</a></blockquote></div></div>
当我调试Facebook sdk.js
时,我看到.getVersion返回&#34;未定义&#34;因此不会渲染小部件。
显然,在加载&
时,Facebook无法处理由&
而非sdk.js
分隔的传递查询参数。出于验证原因,我已将代码更改为&
。
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&version=v2.3";
答案 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;, 这不是有效的代码