J'utilise le sdk Facebook JS et j'ai créé une nouvelle application aujourd'hui . Tout est configuré correctement . Utiliser la fonction init comme:
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'));
mais j'ai un message d'erreur:
** Disclaimer - Ceci est purement spéculation. Semble avoir résolu mon problème.
J'ai eu ce problème sur un projet récent. Je pense que c'est un problème de latence. Le SDK de Facebook nécessite que <div id="fb-root"></div>
soit présent sur la page. Cela devrait être la première chose après la balise d'ouverture du corps. Après cela, vous pourrez voir votre code d’initialisation.
Pour moi, ce problème n'était pas cohérent. Je voyais parfois le bogue et parfois non. Ainsi, ma conclusion est qu’il s’agit d’un problème de latence. Si le SDK ne trouve pas le fb-root
, il doit en créer un. C’est là que je pense que le problème de la latence existe.
Essayez d'ajouter ceci juste après votre balise d'ouverture, mais avant votre FB.init({});
.
<div id="fb-root"></div>
Cela semble avoir résolu le problème pour moi et, espérons-le, aider les autres également. La documentation v1.0 explique la raison de fb-root
, mais la documentation v2.0 ne fait aucune mention de l'élément, probablement parce que le script init l'ajoutera pour vous s'il ne le trouve pas.
Je l'ai obtenu en utilisant all.js au lieu de sdk.js.
Dans votre cas, cela ressemblerait à:
js.src = "//connect.facebook.net/pl_PL/all.js";
au lieu de
js.src = "//connect.facebook.net/pl_PL/sdk.js";
Ajoutez &version=v2.0
à js.src, comme suit:
(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'));
Ce problème m'a tourmenté pendant un moment. J'ai essayé plusieurs des idées énumérées ici, telles que changer le numéro de version et déplacer/supprimer le fb-root
.
Ce qui fonctionne enfin pour moi est de supprimer la fonction window.fbAsyncInit
entière et de spécifier les propriétés init
dans le hachage de sdk.js
. Par exemple:
<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>
Bien sûr, vous pouvez omettre un paramètre pour utiliser sa valeur par défaut.
Je ne trouve cette approche documentée nulle part, utilisez-la à vos risques et périls. Heureusement, je mettais à niveau un ancien site de v1.x
à v2.x
et il utilisait cette technique lors du chargement de all.js
.
j'ai remplacé ceci
js.src = "//connect.facebook.net/en_US/sdk.js";
avec ça
js.src = "//connect.facebook.net/en_US/all.js";
et a travaillé :)
Cela m’arrivait aussi avec beaucoup d’incohérence. Quelque part, mon intuition a dit, cela doit être un problème de timing. Suite au débogage, vous avez découvert une erreur dans la console du développeur en exécutant manuellement "FB.login()
". L'erreur disait: " init pas appelé avec une version valide ".
Dans mon cas, j’ajoutais //connect.facebook.net/en_US/sdk.js
en tant que balise de script dans l’en-tête de la page html et le window.fbAsyncInit
est arrivé dans un autre fichier juste après. Cela m'a indiqué comme un problème de synchronisation et par conséquent, j'ai échangé ces 2 balises de script. Maintenant, une fois que j'avais inclus window.fbAsyncInit
avant d'inclure //connect.facebook.net/en_US/sdk.js
, le problème avait disparu. J'espère que cela aide les autres.
C’était le seul correctif qui éliminerait l’erreur 100% du temps.
Vous pouvez recréer cette erreur en supprimant votre fichier FB.init. Ce qui confirme que, bien que le fichier sdk.js ait été chargé et que l'espace de noms FB existe, FB.init n'a pas été appelé au moment où nous avons essayé d'utiliser les méthodes FB ailleurs dans nos scripts.
Nous devons donc nous assurer que FB.init a été appelé. J'ai utilisé une approche similaire à cette réponse :
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'));
Ensuite, ailleurs, toute référence à FB peut être faite comme ceci:
fbApi.ready(function() {
FB.XFBML.parse($("#fb-comments"));
});
Essayez ce code:
setInterval(
function() { FB.api('/me/',
function(r) { console.log('response: ', r); })
}, 5000);
J'ai remarqué que lorsque j'essaie d'obtenir info, fb n'est toujours pas initialisé.
Je l'ai corrigé en ajoutant mon code d'initialisation à la fin de:
FB.getLoginStatus(function(response) { init(); });
J'ai résolu cette erreur en chargeant le script sur le document prêt au lieu du chargement du document.
Par exemple, cela donnait l'erreur environ 10% du temps:
$(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'));
});
alors que cela fonctionne tout le temps:
$(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'));
});
Faites attention lorsque vous appelez FB api après init. Init semble synchrone, mais window.fbAsyncInit ne l’est pas, vous devez donc attendre son exécution. Mon exemple à reproduire concerne la plate-forme de navigateur Phonegap, mais après avoir vérifié le code du plug-in de Facebook, je suis sûr qu'il peut également être reproduit dans un environnement javascript pur.
C'était mon code qui déclenche l'erreur:
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));
});
Voici comment je l'ai corrigé:
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));
});
});
}
Je suis sûr que le code suivant jettera dans le navigateur, mais je n'ai pas le temps de le vérifier:
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
https://
dans l'URLjs.src = "https://connect.facebook.net/en_US/sdk.js";
Je n'aurais pas cru cela non plus, mais la seule différence entre ce que Facebook a dans son exemple de code actuel et ce que j'ai est https://
au lieu de //
pour l'URL.
Mettre à jour pour être https: // semble l'avoir corrigé pour moi et je ne peux pas dupliquer l'erreur.
De même, si vous effectuez des vérifications ailleurs dans votre code pour voir si FB
est défini, assurez-vous de vérifier if (window.FB)
et non if (FB)
, sinon vous obtiendrez une erreur.
// call after manually adding DOM nodes containing FB widgets
if (window.FB)
{
window.FB.XFBML.parse()
}
Si vous utilisez TypeScript, vous devez ajouter quelque chose comme ceci:
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);
}
SINGLE INCLUDE - assurez-vous que l'API JavaScript de Facebook n'est pas incluse plus d'une fois sur votre page.
(C'était mon problème)
J'ai eu le même problème lorsque j'ai essayé d'intégrer un simple post Facebook dans un article que j'écrivais.
<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>
Quand j'ai débogué le sdk.js
de Facebook, j'ai vu que la .getVersion renvoyait "undefined" et ne rendait donc pas le widget.
Apparemment, Facebook ne peut pas gérer le passage de paramètres de requête séparés par &
au lieu de &
lors du chargement du sdk.js
. J'avais changé mon code en &
pour des raisons de validation.
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";
L'erreur s'est produite chaque fois que j'ai redirigé vers une page (navigateur Edge) qui avait un plugin fb-page.
Si je rafraîchis la page cela fonctionnerait. Si j'y arrivais par un lien hypertexte, l'erreur serait renvoyée.
Corrigé en ajoutant sdk.js?d=" + new Date().toISOString();
au 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'));
Dans les applications à page unique, vous avez moins de contrôle sur l'ordre dans lequel le code sera exécuté. Parfois, le script sera chargé au moment où vous appelez votre code, parfois pas.
Pour que cela fonctionne, que le script facebook soit déjà chargé ou non, je vérifie si la variable globale FB
est déjà définie au moment de l'exécution du code. Si oui, je fais juste une initialisation normale, sinon je fournis le rappel.
Ceci est mon code:
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'
});
}
}
Dans mon fichier html, je fournis simplement le script donné par facebook, et dans mon code, je peux appeler initializeFacebookSdk()
où et quand je le souhaite:
<!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>
Nous utilisons notre propre API qui fait cela:
_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));
}
Vous utilisez le plugin cordova-plugin-facebook4. Il s'agit d'un message d'erreur personnalisé indiquant que l'init n'a pas fini lorsque la fonction api de facebook est appelée. Étant donné que le plug-in ne donne pas une waitForInitialize
à l'aide de setTimeout, il est préférable de réessayer la méthode 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. */