Функция FB init дает неправильную ошибку версии
Я использую SJK для Facebook, и сегодня я создал новое приложение.
Все настроено правильно.
Использование функции 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 и до сих пор не повезло.
Что я здесь делаю неправильно?
Ответы
Ответ 1
** Отказ от ответственности - это чисто спекуляция. Кажется, решил мою проблему.
У меня была эта проблема в недавнем проекте. Я думаю, что это проблема с задержкой. В SDK для Facebook требуется <div id="fb-root"></div>
находиться на странице. Это должно быть первым делом после тега открытия тела. После этого вы можете увидеть свой код инициализации.
Для меня эта проблема не была последовательной. Иногда я вижу ошибку, а иногда и не буду. Таким образом, мой вывод о том, что это проблема с задержкой. Если SDK не может найти fb-root
, он должен создать его. Здесь я полагаю, что проблема с задержкой существует.
Попробуйте добавить это сразу после тега тега открытия, но перед вашим FB.init({});
.
<div id="fb-root"></div>
Это, похоже, решило проблему для меня и, надеюсь, поможет и другим. В документации v1.0 обсуждается причина fb-root
, но в документах v2.0 не упоминается элемент, вероятно, потому что init script добавит его вам, если он не найдет его.
Ответ 2
Я получил его работу, используя all.js вместо sdk.js.
В вашем случае это будет выглядеть так:
js.src = "//connect.facebook.net/pl_PL/all.js";
вместо
js.src = "//connect.facebook.net/pl_PL/sdk.js";
Ответ 3
Добавьте &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'));
Ответ 4
Эта проблема напала на меня некоторое время. Я пробовал многие из перечисленных здесь идей, таких как изменение номера версии и перемещение/удаление 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
.
Ответ 5
i заменил это
js.src = "//connect.facebook.net/en_US/sdk.js";
с этим
js.src = "//connect.facebook.net/en_US/all.js";
и работал:)
Ответ 6
Это было единственное исправление, которое устранило бы ошибку 100% времени.
Вы можете восстановить эту ошибку, удалив свой FB.init. Это подтверждает, что хотя sdk.js был загружен и существовало пространство имен FB, FB.init не был вызван к моменту, когда мы пытались использовать методы FB в других местах наших скриптов.
Итак, нам нужно убедиться, что 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"));
});
Ответ 7
Это происходило со мной тоже с большой несогласованностью. Где-то моя догадка сказала, что это вопрос времени. Дальнейшая отладка обнаружила ошибку в консоли разработчика вручную, выполнив "FB.login()
". Ошибка сказала: "init не вызывается с допустимой версией".
В моем случае я добавлял //connect.facebook.net/en_US/sdk.js
в качестве тега script в заголовок html-страницы, а window.fbAsyncInit
появился в другом файле сразу после этого. Это указывало на меня как на проблему времени, и поэтому я поменял эти теги script. Теперь, когда я включил window.fbAsyncInit
, прежде чем включать //connect.facebook.net/en_US/sdk.js
, проблема исчезла. Надеюсь, это поможет другим.
Ответ 8
Попробуйте этот код:
setInterval(
function() { FB.api('/me/',
function(r) { console.log('response: ', r); })
}, 5000);
Я заметил, что когда я пытаюсь получить информацию, fb все еще не инициализируется.
Я исправил его, добавив мой код инициализации до конца:
FB.getLoginStatus(function(response) { init(); });
Ответ 9
Я решил эту ошибку, загрузив script на документе, готовый вместо загрузки документа.
Например, это дало ошибку около 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'));
});
Ответ 10
Остерегайтесь, когда вы вызываете FB api после init. 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
Для приложений с одной страницей (Реагируйте в моем случае)
В одностраничных приложениях вы меньше контролируете порядок выполнения кода. Иногда скрипт будет загружен к моменту вашего вызова кода, иногда нет.
Чтобы он работал независимо от того, загружен ли скрипт 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>
Ответ 12
Мы используем наш собственный 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));
}
Ответ 13
У меня была такая же проблема, когда я попытался встроить простую публикацию в 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 вернул "undefined" и, таким образом, не отображал виджет.
По-видимому, 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";
![Facebook sdk debug getVersion]()
Ответ 14
Ошибка произошла каждый раз, когда я перенаправлялся на страницу (Edge Browser), в которой был плагин fb-page.
Если бы я обновил страницу, это сработало бы. Если бы я попал туда через гиперссылку, он бы выбросил ошибку.
Исправлено, добавив sdk.js?d=" + new Date().toISOString();
в 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?d=" + new Date().toISOString();
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
Ответ 15
Вы используете плагин cordova-plugin-facebook4, и это настраиваемое сообщение об ошибке, которое означает, что init не закончил работу с функцией facebook api. Так как плагин не дает waitForInitialize
, используя setTimeout, а затем повторная попытка 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
SINGLE INCLUDE - убедитесь, что API JavaScript JavaScript не включен более одного раза на вашу страницу.
(Это была моя проблема)
Ответ 17
Убедитесь, что вы используете https://
в URL-адресе
js.src = "https://connect.facebook.net/en_US/sdk.js";
Я бы тоже не поверил в это, но единственное различие между тем, что у Facebook есть в их текущем примере кода и том, что у меня есть, это https://
вместо //
для url.
Обновление 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);
}
Ответ 18
У меня была та же проблема, и я думаю, что нашел основную причину!
Первопричина
В моем случае мы динамически внедряли FB SDK на веб-сайт нашего клиента. Однако некоторые наши клиенты уже добавили FB SDK через другие плагины. Эти плагины имеют разные ID и версию приложения.
Поэтому в зависимости от задержки некоторые плагины вызывают init
до/после нашего
Решение
Если вы являетесь владельцем сайта, на котором вы внедряете SDK, убедитесь, что другие плагины не внедряют FB SDK и не вызывают init
другую версию и идентификатор приложения
Если вы не являетесь владельцем сайта, по крайней мере, попробуйте внедрить 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);
}
Ответ 19
В моем случае это была проблема с версией 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
});
};
Ответ 20
window.fbAsyncInit = function() {
FB.init({
appId : 'xxxx', // App ID
status : false,
version: 'v2.0',
cookie : true,
xfbml : false // parse XFBML
});
};
Существует ошибка версия: 'v2.0',
Это недопустимый код