Facebook登录按钮OnLogin回电两次



每个文档,html属性'onlogin'可用于在登录完成后运行回调函数

但是,我们始终保持提供的功能运行两次,在实际工作时会引起问题。

尽管我们可以通过计数器来抓住它的运行次数,但我宁愿了解为什么会发生这种情况并修复它,而不是应用解决方法。整个代码在下面(不会在摘要中运行):

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>facebook login test</title>
	<script src="/Vendors/jQuery/jquery-3.2.1.min.js"></script>
</head>
	<body>
		<script>
		window.fbAsyncInit = function() {
			FB.init({
				appId      : 'foobar123456', // see https://developers.facebook.com/apps/
				cookie     : true,
				xfbml      : true,
				version    : 'v2.11' // see https://developers.facebook.com/docs/javascript/quickstart
			});
			
			FB.AppEvents.logPageView();   
			
		};
		(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>
		<!-- LOGIN BUTTON scope at: https://developers.facebook.com/docs/facebook-login/permissions/ -->
		<div class="fb-login-button" data-width="250" data-max-rows="1" data-size="large" onlogin="fbLoginHandler" data-scope="public_profile,email" data-button-type="login_with" data-show-faces="false" data-auto-logout-link="true" data-use-continue-as="true"></div>
		<script>
			console.log("reached script tag");
			var timesfbLoginHandlerFired = 0;
			var fbLoginHandler = ()=>{
				timesfbLoginHandlerFired++;
				console.log("fbLoginHandler fired ["+timesfbLoginHandlerFired+"] times");
			};
		</script>
	</body>
</html>

和控制台:

Navigated to https://fbtest.dev/fblogin <- on page load
reached script tag <- on page load
XHR finished loading: POST "https://www.facebook.com/ajax/bz". <- on page load
XHR finished loading: POST "https://www.facebook.com/ajax/bz". <- on facebook login prompt window opening
fbLoginHandler fired [1] times <- on login complete
fbLoginHandler fired [2] times <- on login complete

我更快的解决方法如下:

我刚刚设置了一个称为fblogin_done

的变量
fblogin_done = 0;

在执行两次的功能中,我将计数器和一个带有计时器的阻止器

function CheckLoginState() {
    if (fblogin_done == 1) return; // avoid twice executions
    fblogin_done = 1;
    window.setTimeout(function(){
        fblogin_done = 0; // wait 1 second after a second execution
    }, 1000);
}

一秒钟足以避免执行超过1个,

这似乎与将data-auto-logout-link设置为true

将其设置为false,停止按钮启动onlogin功能两次。

不查看SDK如何处理它,我最好的猜测是,当按钮更改为注销按钮时,它必须第二次检查登录并触发Onlogin函数。

我发现这是处理双重呼叫的一种干净的方式。

function mainLogin() {
   FB.getLoginStatus(function (response) {   // when connected, login, avoids double call                 
      if (response.status === 'connected') {                        
         fbLogin();
      };
   });
}
function fbLogin() {
   FB.api('/me?fields=name,id,email', function (response) {
      if (!jQuery.isEmptyObject(response)) {  //make certain we got a response object
         console.log(response);
         //todo: Get the FB data and process it...
       } else {
          //todo: err handling
       }                
    });
}

最新更新