- PVSM.RU - https://www.pvsm.ru -
Автор материала, разработчик из PayPal, описывает набор утилит для кроссдоменного взаимодействия.
Мы в PayPal пишем много яваскриптового кода, который в конечном счете начинает работать на других веб-сайтах и других доменах. Яркий пример — checkout.js [1], интеграционный скрипт, полностью охватывающий процесс оформления и оплаты заказа с помощью нашего сервиса, позволяющий мерчантам очень просто и непринужденно встраивать нашу кнопку [2] и механизм оформления заказа в свои сайты.
Запуск нашего кода на сторонних сайтах сопряжен с огромным количество рисков и подводных камней, но есть некоторые ключевые моменты:
Array.prototype.toJSON
что привело к поломке JSON.stringify
. Многие веб-сайты включают полизаполнение WeakMap
, которое в отличие от ее нативной версии не работает на междоменных оконных объектах. Поэтому без дополнительных предварительных проверок мы можем доверять только собственному коду.try/catch
с целью получения доступа или задания свойства оконного объекта. Но даже с учетом этого Safari настаивает на том, чтобы в консоли для этого действия появлялась соответствующая ошибка происхождения. Эта проблема превратилась в генератор неразберихи: наши мерчанты писали баг репорты, а мы говорили им что эту ошибку нужно игнорировать.В прошлом году мы решили сосредоточиться на том, чтобы собрать вместе по-настоящему мощный набор инструментов, помогающий избегать подобных ловушек и создавать отличный пользовательский опыт без необходимости постоянно беспокоиться о том, доходят ли сообщения и все ли окна отрисовываются.
Мы открыли весь исходный код набора. Если вы желаете создать взаимодействия, которые работают с вашей системой с других сайтов или просто между разными доменами внутри вашей организации, то поиски заканчиваются здесь.
Сначала о главном. Мы хотели создать толковую заготовку, на базе которой работали бы все запланированные нами инструменты. У нас есть формальный список технологий, которые нам нравятся, но объединить их в некое качественное целое задача не из простых. Мы решили максимально упростить себе работу в будущем и потому всякий раз, когда мы хотим опубликовать новую кросс доменную библиотеку или инструмент, мы форкаем grumbler и начинаем кодить, не беспокоясь о предварительной настройки какой-либо среды или инструментов.
→ Подробнее по ссылке [4]
Первой настоящей технической проблемой, которую мы хотели решить был обмен сообщениями между окнами и айфреймами. Думаете можно просто взять window.postMessage
и начать сыпать сообщениями направо и налево? Подумайте еще раз:
post-robot призван решить все эти проблемы одним махом, предоставляя стабильный и надежный способ отправки сообщений и получения ответов.
→ Подробнее по ссылке [6]
Мы любим пользоваться React, и нам нравится великолепная в своей простоте идея компонентов, работающих по принципу «данные вниз, действия вверх». При этом концепция React нацелена на рендеринг пользовательского интерфейса непосредственно на вашей странице, без каких-либо фреймов или междоменных ограничений. Но есть одно существенное «но»: мы бы никогда не стали даже пытаться загрузить React на сайте, который нам не принадлежит.
Мы спросили себя: а что если включить айфреймы и всплывающие окна в React-подобные компоненты, которым мы могли бы напрямую передавать свойства и обратные вызовы и позволить дочерним окнам напрямую вызывать функции, переданные родителем?
Айфреймы, как правило, для этого не подходят. То есть в обычных ситуациях с помощью window.postMessage
вы можете только отправлять простые объекты и строки вниз айфрейму и обратно вверх его родителю. Но с xcomponent у вас появляется возможность отрисовывать айфрейм вообще без необходимости настраивать какие-либо обработчики сообщений: вы будете просто передавать данные и функции напрямую в айфрейм, и он будет получать напрямую любые свойства, которые вы передадите ему в объекте window.xprops
.
Кроме того, он автоматически настраивает привязки к популярным фреймворкам, таким как React, Angular, Vue и другим, что позволяет вам отрисовывать айфреймы в своем приложении нативным способом без какой-либо необходимости беспокоиться о том, насколько ужасно обычно ведут себя айфреймы.
→ Подробнее по ссылке [8]
→ А вот так мы пользуемся xcomponent в PayPal [2]
Руководствуясь теми же соображениями, что и в случае с grumbler’ом, мы хотели максимально упростить работу над компонентами xcomponent, сделав так, чтобы настройка среды и инструментов не замедляла работу. Все любят, когда можно просто начать кодить.
Поэтому мы выпустили xcomponent-demo — шаблон, который вы можете форкнуть и начать работать. В нем есть все что нужно для компоновки, тестирования, издания и даже статической типизации вашего кода и публикации x-компонентов для общего использования.
Работа с междоменными окнами — сложная штука. Возникает много вопросов. Например, как узнать наверняка, что окно другого домена закрыто? Что его домен совпадает с вашим? Какие у него дочерние элементы? Браузеры предоставляют простые API для некоторых из этих задач, но в каждом браузере все получается по своему.
С cross-domain-utils мы попытались создать библиотеку вспомогательных методов, призванных помочь в работе с распространенными кейсами, упрощающих работу с междоменными окнами и избавляющих вас от необходимости постоянно беспокоиться о получении ошибок или предупреждений в консоли. Инструмент, в числе прочего, позволяет избежать реально странных экстремальных кейсов, наподобие вот такого:
Edge, как всегда, в своем репертуаре.
Хранение оконных объектов — процесс затратный с точки зрения оперативной памяти, даже если окно, референс которого вы храните, закрыто.
WeakMaps идеально подходит для хранения данных об окнах, поскольку:
Единственная проблема заключается в том, что многие существующие WeakMap прокладки пытаются вызвать Object.defineProperty
по ключу, что сразу же приводит к неудаче в случаях, когда ключ представляет собой междоменное окно с ограниченным доступом.
Cross-domain-safe-weakmap, напротив, разработана так, чтобы сделать работу с междоменными окнами с помощью их ключей и нативной реализации WeakMap (если она доступна) максимально предсказуемой и надежной.
Многие браузеры просто лишают приоритета все, что отправляется в setTimeout
, если вкладка браузера, в которой отрабатывает ваш код находится не в фокусе. Поэтому когда вы работаете над чем-то, что должно работать во всплывающем окне, и вам при этом нужно отправить сообщение родителю и запросить его что-либо сделать… В таком случае любой setTimeout
конкретно затормозит работу родителя.
Поэтому выход простой: отказываемся от setTimeout
для любых критичных путей выполнения кода, верно?
Проблема в том, что многие из существующих промежуточных промис-оболочек в отсутствие помощников вроде setImmediate
прибегают к использованию setTimeout
, чтобы гарантировать, что переданная .then
функция вызывается асинхронно. Поэтому если вы хотите воспользоваться промисами в самых разных браузерах и делать при этом так, чтобы код выполнялся в окнах без фокус, тогда вам немного не повезло.
zalgo-promise пытается решить эту проблему путем перевода всех промисов в синхронный режим по умолчанию. Это значит, что если они будут разрешены синхронно, то передаваемая .then()
функция будет также вызвана синхронно. Она называется zalgo-promise потому что мы в буквальном смысле решили выпустить zalgo [10] (после тщательного рассмотрения всех за и против).
→ Подробнее по ссылке [11]
Один из важных моментов, связанных с запуском кода на других доменах, заключается в том, что вам необходимо знать, что происходит и как люди пользуются вашими продуктами. И уж по крайней мере вам нужно знать о тех случаях, когда код вызывает какие-либо ошибочные сценарии или ломает чей-то сайт.
С другой стороны, нет никакой необходимости отправлять один сигнал за другим или писать в журнал сотню запросов подряд для каждого события, для которого вы хотели зафиксировать.
beaver-logger пытается решить эту проблему путем отбора и компоновки логов и периодического их сбрасывания на ваш сервер. В его комплект даже входит серверный компонент узла для получения логов, но вы можете свободно приспосабливать его как хотите для любой любимой платформы.
CORS — головная боль. Получение корректных заголовков требует настройки на сервере каждой отдельной конечной точки. А если речь идет не о GET-запросе, то CORS заставляет делать дополнительные операции обмена, чтобы определить, безопасно ли делать тот или иной конечный запрос.
fetch-robot — новый экспериментальный модуль, нацеленный на решение этой проблемы. Он позволяет вам публиковать в одном месте манифест, определяющий URL-ы, которые могут быть вызваны, а также то, кем они могут быть вызваны и какие заголовки и другие поля при этом могут быть использованы.
Он показывает содержимое URL-ов с другим доменом через айфрейм. С помощью post-robot этот же айфрейм проводит через себя все сообщения, что позволяет избежать проблемы дополнительных взаимодействий (поскольку все проверки выполняются на стороне клиента, внутри доверенного фрейма).
→ Подробнее по ссылке [12]
Спасибо всем за чтение, и если у вас есть какие-нибудь идеи по поводу того, каких инструментов не хватает в наборе по кроссдоменному взаимодействию или что в них можно улучшить, пожалуйста, напишите автору!
— Дэниел, команда разработки чекаут-инструментов PayPal
Автор: Wirex
Источник [13]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/266610
Ссылки в тексте:
[1] checkout.js: https://github.com/paypal/paypal-checkout
[2] кнопку: https://medium.com/@bluepnume/less-is-more-reducing-thousands-of-paypal-buttons-into-a-single-iframe-using-xcomponent-d902d71d8875
[3] Image: https://github.com/krakenjs/grumbler
[4] Подробнее по ссылке: https://medium.com/@bluepnume/introducing-grumbler-an-opinionated-javascript-module-template-612245e06d00
[5] Image: https://github.com/krakenjs/post-robot
[6] Подробнее по ссылке: https://medium.com/@bluepnume/introducing-post-robot-smart-cross-domain-messaging-from-paypal-bebf27c8619e
[7] Image: https://github.com/krakenjs/xcomponent
[8] Подробнее по ссылке: https://medium.com/@bluepnume/introducing-xcomponent-seamless-cross-domain-web-components-from-paypal-c0144f3e82bf
[9] Image: https://github.com/krakenjs/cross-domain-safe-weakmap
[10] выпустить zalgo: https://oren.github.io/blog/zalgo.html
[11] Подробнее по ссылке: https://medium.com/@bluepnume/intentionally-unleashing-zalgo-with-promises-ab3f63ead2fd
[12] Подробнее по ссылке: https://medium.com/@bluepnume/reinventing-cross-origin-requests-without-cors-b9c4cb645376
[13] Источник: https://geektimes.ru/post/294717/
Нажмите здесь для печати.