FB JS SDK: обратный вызов FB.Login дважды запущен в IE 11

У меня странная проблема с реализацией JS FB-SDK. Все работает безупречно, за исключением IE 11. Метод FB.loginофициальный JS-API, который получает обратный вызов, запускает его дважды после появления диалогового окна OAuth и авторизации приложения пользователем. В первый раз он возвращает ответ с параметром authResponse как undefined, во второй раз он имеет все ожидаемые значения.

Я совершенно не понимаю, почему это происходит. Я дважды и трижды проверил, что 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.info("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.info('FB not loaded yet!')
        return;
      } else if (EP.facebook.connected && !EP.facebook.emailDeclined) {
        console.info('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.info("FB.login response: ", response);
          if (response.authResponse) {
            EP.facebook.connected = true;
            return
          } else {
            return;
          }
        }, fbLoginParams);
      }
    }

    $("#fblogin").on("click", Facebook)
})(jQuery)

Чтобы это работало, он должен обслуживаться с сервера с доменом, отличным от локальный хост, из-за ограничений приложения fb и обслуживаться через https. Я использовал нгрок для сопоставления URL-адреса https с моим локальным сервером разработки. Локальный сервер разработки был просто пакет, запущенным с выполнения parcel build index.html, а затем parcel index.html. Конечно, вам нужно настроить FB-приложение разработчика с действительным URI перенаправления OAuth (ngrok). Помните также, что вы должны выйти из Facebook, прежде чем тестировать это. Вот результаты после входа в FB и авторизации тестового приложения FB:

FB JS SDK: обратный вызов FB.Login дважды запущен в IE 11

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

Спасибо

Я не могу воспроизвести проблему только с приведенным выше кодом. Я пытаюсь скомпилировать код coffeescript в код javascript, но получаю ошибку. Предоставьте больше кодов, связанных с проблемой, включая html-коды, скрипты, полифиллы и т. д. Вы можете обратиться к этому, чтобы предоставить минимальный воспроизводимый пример.

Yu Zhou 19.06.2019 09:37

@YuZhou попытается создать воспроизводимый пример и вернуться с ним!

tommyalvarez 19.06.2019 17:26

@YuZhou Ну вот, смотрите мои правки. Надеюсь, этот минимальный пример работает для вас. Пытался использовать codeandbox, но не работает с IE11, поэтому... не оставил мне другого выбора, кроме как вставить минимальный необходимый код с небольшими инструкциями о том, как попытаться воспроизвести среду

tommyalvarez 21.06.2019 07:06
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
3
1 391
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Можете ли вы придумать обходной путь, чтобы игнорировать первый ответ из примера кода, учитывая, что он очень похож на тот же ответ, который происходит, когда пользователь отклоняет авторизацию или закрывает диалоговое окно без предоставления доступа?

tommyalvarez 25.06.2019 21:00

Единственный обходной путь, который я могу найти, - это поставить console.info("FB.login response: ", response); после if (response.authResponse) {, тогда ответ появляется только при успешном подключении.

Yu Zhou 26.06.2019 10:34

Хм, это не помешает. Дело в том, что на более высоком уровне я оборачиваю это в промисы, и когда приходит неопределенный ответ, что иногда бывает в случае закрытых диалогов по желанию пользователя, я отклоняю промис и определенные триггеры бизнес-логики, которые влияют на пользовательский интерфейс. . Пользователи IE 11 никогда не смогут подключиться или увидеть согласованный пользовательский интерфейс, поскольку обещание уже было отклонено, несмотря на получение второго ответа.

tommyalvarez 26.06.2019 18:46
Ответ принят как подходящий

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

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

Другие вопросы по теме