В этой статье мы узнаем, как закрыть внешнюю вкладку с другим источником из вашего приложения, изучив три концепции:
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 windowhttps://www.parent.com
we can postMessage tohttps://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.
Спасибо за чтение, надеюсь, вы найдете его полезным