У меня странная проблема с реализацией JS FB-SDK. Все работает безупречно, за исключением IE 11. Метод FB.login
официального JS API, который получает обратный вызов, запускает его дважды после появления диалогового окна OAuth и авторизации приложения пользователем. В первый раз он возвращает ответ с параметром authResponse
как неопределенным, во второй раз он имеет все ожидаемые значения.
Я совершенно не понимаю, почему это происходит. Я дважды и трижды проверил, что FB.login
нигде не вызывается дважды. Кто-нибудь когда-нибудь преодолевал этот сценарий или заставлял работать вход через FB с IE?
Он отлично работает в Edge, Firefox, Chrome и даже в мобильных браузерах: chrome и safari в iOS, Android Chrome.
Я предоставляю минимальную воспроизводимую демонстрацию кода.
### index.html
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>FB IE 11</title>
</head>
<body>
<div id="fb-root"></div>
<button
id="fblogin">
Sign in with Facebook
</button>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.8/angular.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js'></script>
<script src="./script.js"></script>
</body>
</html>
### script.js
(function($) {
var EP = { facebook: {} }
EP.facebook.init_was_called = false;
EP.facebook.promise = $.Deferred();
EP.facebook.connected = false;
EP.facebook.emailDeclined = false;
EP.facebook.loginRetryCount = 0;
window.fbAsyncInit = () => {
console.log("window.fbAsyncInit callback triggered by Facebook SDK");
window.FB.init({
appId: "418117192377109", // should be your app id when testing
cookie: true, // Store fbsr_xxx cookie
xfmbl: false,
version: "v3.2",
status: true // Fetch user's facebook login status
});
EP.facebook.promise.resolve();
};
// Use this to wrap any calls where we're not sure the FB api has been bootstrapped
EP.facebook.afterFacebookInitialized = callback => {
return $.when(EP.facebook.promise).then(callback);
};
$(function() {
// Always parseFBML
EP.facebook.afterFacebookInitialized().done(function() {
window.FB.XFBML.parse();
});
if (EP.facebook.init_was_called) {
return;
}
EP.facebook.init_was_called = true;
// This only needs to be called once per full page load (on The Post and when showing login screen)
$.getScript("https://connect.facebook.net/en_US/sdk.js");
});
var Facebook = function() {
var fbLoginParams;
if (!window.FB) {
console.log('FB not loaded yet!')
return;
} else if (EP.facebook.connected && !EP.facebook.emailDeclined) {
console.log('Already logged in to FB')
return;
} else {
fbLoginParams = {
scope: "email"
};
if (EP.facebook.emailDeclined) {
fbLoginParams.auth_type = "rerequest";
}
return window.FB.login(function(response) {
console.log("FB.login response: ", response);
if (response.authResponse) {
EP.facebook.connected = true;
return
} else {
return;
}
}, fbLoginParams);
}
}
$("#fblogin").on("click", Facebook)
})(jQuery)
Чтобы это работало, он должен обслуживаться с сервера с доменом, отличным от localhost, из-за ограничений приложения fb и обслуживаться через https. Я использовал ngrok для сопоставления URL-адреса https с моим локальным сервером разработки. Локальный сервер разработки был просто parcel, начиная с выполнения parcel build index.html
, а затем parcel index.html
. Конечно, вам нужно настроить FB-приложение разработчика с действительным URI перенаправления OAuth (ngrok). Помните также, что вы должны выйти из Facebook, прежде чем тестировать это. Вот результаты после входа в FB и авторизации тестового приложения FB:
Вот они, 2 ответа, великолепные!
Спасибо