В этой статье мы узнаем, как закрыть внешнюю вкладку с другим источником из вашего приложения, изучив три концепции:

1- Что означает межоконное общение

2- В чем проблема, когда два окна с разным происхождением разговаривают друг с другом

3- Решение для обмена сообщениями между окнами

1- Что означает межоконное общение

Политика «Одинаковый источник» (один и тот же сайт) ограничивает доступ окон и фреймов друг к другу.

Идея состоит в том, что если у пользователя открыты две страницы: одна с сайта john-smith.com, а другая - с gmail.com, то они не захотят, чтобы скрипт с сайта john-smith.com читал нашу почту с gmail.com. . Итак, цель политики «Одинаковое происхождение» - защитить пользователей от кражи информации.

Считается, что два URL-адреса имеют «одно и то же происхождение», если у них одинаковый протокол, домен и порт.

Политика «Одинаковый источник» гласит:
если у нас есть ссылка на другое окно, например всплывающее окно, созданное с помощью window.open или окна внутри ‹iframe›, и это окно происходит из того же источника, тогда у нас есть полный доступ к этому окну.
В противном случае, если оно происходит из другого источника, мы можем ' t получить доступ к содержимому этого окна: переменные, документ, что угодно. Единственное исключение - местоположение: мы можем его изменить (перенаправив пользователя). Но мы не можем прочитать местоположение (поэтому мы не можем видеть, где сейчас находится пользователь, утечки информации нет).

2-В чем проблема, когда два окна с разным происхождением разговаривают друг с другом

Проблема, с которой я столкнулся в нашем приложении во время процесса оформления заказа, мы хотим открыть безопасное окно 3D и отслеживать изменение его URL-адреса с помощью этого сценария:

Нажмите кнопку в своем приложении https://www.site.com , чтобы открыть форму с другим доменом https://www.form.com на новой вкладке, после нажатия кнопки отправки в форме, а затем перенаправления на другой другой домен https://www.success.com на той же вкладке, здесь возникает проблема :

мы хотим закрыть эту вкладку https://www.success.com, как мы можем это сделать ?!
Есть два традиционных решения, но они не работают:

  • window.open ()

Как мы видим в консоли, мы не можем получить доступ к местоположению https://www.form.com , потому что он имеет другой домен нашего сайта, поэтому мы не можем отслеживать изменение URL-адреса на https://www.success.com и закрыть это окно.

  • iframe

Также iframe дает тот же результат, что и window.open.

3-Решение для обмена сообщениями между окнами

Интерфейс postMessage позволяет окнам общаться друг с другом независимо от того, из какого они источника.
Таким образом, это способ обойти политику «Одинаковый источник». Это позволяет окну из https://www.site.com общаться с https://www.success.com и обмениваться информацией, но только если они оба согласны и вызывают соответствующие функции JavaScript. Это делает его безопасным для пользователей.

Интерфейс postMessage состоит из двух частей:

  • postMessage
    Окно, которое хочет отправить сообщение, вызывает метод postMessage принимающего окна. Другими словами, если мы хотим отправить сообщение на сайт, мы должны вызвать site.postMessage (data, targetOrigin)
    Аргументы:
    - данные → Данные для отправки.
    - targetOrigin → Указывает источник для целевого окна, так что только окно из данного источника получит сообщение.
    Указание targetOrigin гарантирует, что окно получит данные только в том случае, если оно все еще находится на нужном сайте. Важно, если данные являются конфиденциальными.
From this window https://www.parent.com we can postMessage to https://www.child.com

  • onmessage
    Чтобы получить сообщение, целевое окно должно иметь обработчик события сообщения. Он срабатывает при вызове postMessage (и при успешной проверке targetOrigin).
    Объект события имеет особые свойства:
    - Данные → Данные из postMessage.
    - Источник → Источник отправителя.

Вот пример:

Решение исходит из этой идеи: мы получаем сообщение об успешном завершении https://www.success.com в событии onmessage и закрываем это окно из нашего приложения https://www.site.com

но как мы можем реализовать это решение:

  • Создайте дочерний компонент и вставьте его в реагирующий маршрутизатор, чтобы включить маршрутизацию к нему. В этом компоненте мы можем открыть безопасную страницу 3D с помощью пакета «response-iframe».

  • Установите пакет «response-window-opener», чтобы открыть дочернюю страницу с окном 3D Secure в новой вкладке.

Заключение

связь между двумя окнами с разными доменами может быть легко осуществлена ​​через событие postMessage и onmessage.

Спасибо за чтение, надеюсь, вы найдете его полезным