Facebook登录按钮onlogin回调触发两次

Gav*_*vin 7 javascript jquery facebook facebook-login

根据文档,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>
Run Code Online (Sandbox Code Playgroud)

和控制台:

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
Run Code Online (Sandbox Code Playgroud)

Jr *_*mnz 2

我的更快的解决方法如下:

我刚刚设置了一个名为 fblogin_done 的变量

fblogin_done = 0;
Run Code Online (Sandbox Code Playgroud)

在执行两次的函数中,我放置了一个计数器和一个带有计时器的拦截器

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);
}
Run Code Online (Sandbox Code Playgroud)

对我来说,一秒钟就足以避免超过 1 次处决,