У меня странная проблема с реализацией 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 build index.html, а затем parcel index.html. Конечно, вам нужно настроить приложение FB для разработчика с действительным URI перенаправления OAuth (ngrok). Помните также, что вы должны выйти из fb перед тестированием. Вот результаты после входа в FB и авторизации тестового приложения FB:

enter image description here

Вот они, 2 ответа, великолепно!

Благодарность

5
tommyalvarez 19 Июн 2019 в 02:44

2 ответа

Лучший ответ

Проблема была ошибка в Facebook! Я разместил в их справочном центре сообщения об ошибках, описал проблему, и они исправили ее. Разрешение на испанском языке, но вы можете проверить здесь.

Конечно, они не указали причину проблемы, но протестировали сейчас, и она работает, как ожидалось.

1
tommyalvarez 4 Июл 2019 в 19:12

Я воспроизвел проблему на своей стороне. После использования fiddler для сравнения сетевого трафика между IE и другими браузерами я обнаружил, что шаг входа в систему будет направлен на ссылку-> https://www.facebook.com/dialog/close_window/?app_id=xxxxxxxxx&connect=0 в IE11. Вы можете увидеть, как эта страница мигает при входе в IE: введите описание изображения здесь В других браузерах этого не произойдет. Думаю, это причина двух ответов. Это может быть некоторая проблема с IE, или API разработан таким образом в IE.

1
Yu Zhou 25 Июн 2019 в 06:49