@izheme
Познаю мир

Какие проблемы прямой вставки кода виджета в код стороннего сайта?

Привет, сообщество!

Недавно я пришел в команду, где работают над проектом, идея которого
заключается в том, что пользователи могут создать форму на нашей платформе, а затем могут вставить ее на свой сайт (отправка данных из формы идет также в наш проект и нашу БД). Фактически, это виджет. В общем, это клон: jotform.com только со своим блэкджэком.

Собственно, проблема вот в чем. Текущая реализация виджета формы сделана на Vue и так, что интеграция идет прямиком в код внешнего сайта. Т.е. наш DOM и JS прямиков в DOM сайта.

И зашел у нас с тимлидом спор. Тимлид говорит, что фишка проекта - это вставка прямиком в код и возможность владельцев сайта влиять на код формы (типа CSS применить). А JS легко через namespace изолировать.

Мое мнение, что такой способ интеграции это просто дичь. И так делать нельзя. Нужно использовать iframe или веб-компонент. А для влияния на CSS просто разрешить указывать свой CSS через поле в настройке формы.

Уважаемые знатоки, пожалуйста, выскажите свое мнение о подходах. Какие могут быть проблемы при прямой вставке в код неизвестного сайта? Действительно ли легко в данном случае изолировать JS и проблемы останутся только с влиянием CSS/HTML?

P.S. Если есть ссылки на интересные материалы по теме, особенно на английском, буду премного благодарен.
  • Вопрос задан
  • 505 просмотров
Решения вопроса 3
@izheme Автор вопроса
Познаю мир
Еще раз благодарю всех принявшим участие в дискуссии. Наконец-то смог найти немного времени и написать небольшой обобщающий материал, может кому-то пригодится.

Итак, ситуация. Вам необходимо сделать возможность вставки своих виджетов в код сторонних сайтов. Для реализации этого сторонний сайт вставляет в свой код ваш JS-код. Далее ваш JS код вставляет виджет. Виджет можно вставить либо прямо в код страницы (далее прямая вставка в DOM) либо создать Iframe. Рассмотрим потенциальные проблемы обоих подходов.

JS конфликты
Прямая вставка в DOM
Здесь не должно быть конфликтов, когда используется “пространство имен”. Но при использовании сторонних библиотек, некоторые из них могут обращаться напрямую к window и это невозможно контролировать. Я столкнулся с проблемой когда vuetify обращается к window.$vue из своего кода и просто падает.

Iframe
Полная инкапсуляция, конфликты исключены

CSS конфликты
Прямая вставка в DOM
Потенциально очень серьёзные конфликты. Код внешнего сайта влияет на виджет, код виджета влияет на внешний сайт. Ваш виджет ломает внешний сайт, внешний сайт ломает ваш виджет.

Iframe
Полная инкапсуляция, конфликты исключены

Cookies (описанное ниже так же относится и к localStorage)
Если необходимо отправлять ваши кукисы из виджета

Прямая вставка в DOM
Мы не можем отправлять кукисы третьей-стороны из JS. Если использовать для отправки кукиса заголовки с сервера во время загрузки статики или скрытый iframe, то браузер будет опознавать их как кукисы третьей стороны. По современным оценкам кукисы третьей стороны отключены у 25-50% пользователей. И тренд такой, что это число будет только расти.

Iframe
Мы можем устанавливать свои кукисы, как кукисы первой стороны. Возможно, для некоторых браузеров, потребуется выполнить POST запрос для одобрения установки кукисов.

Безопасность
Прямая вставка в DOM
Если ваш виджет должен общаться с вашим сервером, то прямая вставка - это полный провал в безопасности. Для возможности выполнения запросов вам необходимо будет включить CORS (отключить same-origin policy). Это приведет к тому, что уязвимость, позволяющая исполнять код на внешнем сайте, позволит злоумышленнику отправлять запросы на ваш сервер от чужого имени, при стечении обстоятельств.

Еще одна проблема, если ваш виджет предоставляет какой-то функционал конечным посетителям сайта, то все их данные становятся доступны внешнему сайту (как владельцу, так и злоумышленнику способному интегрировать код). Так же владелец сайта сможет отправлять запросы от их имени. Короче, это фиаско.

Iframe
Продолжаем использовать same-origin policy. Данные виджета изолированы.

Заключение: единственный адекватный вариант - вставка через iframe.

P.S. Тимлида я обыграл. Но меня поражает: как люди с такими познаниями становятся тимлидами с зп >700к (это не Россия, но все равно дофига)?!
Ответ написан
Комментировать
nikolayshabalin
@nikolayshabalin
Автор профессиональных курсов в HTML Academy
А в чем проблема изолирования JS?

В es5 функциональная область видимости. В es6 блочная. Этих знаний достаточно, чтобы сделать железобетонный JS. Ну и используйте переменные с блочной областью видимости - let, const.

(function(d, w){
//ваш код
})(document, window)


и всё ваш код изолирован.

По-поводу HTML тоже проблем нет, а вот с CSS вы хапанёте очень сильно. Нужно будет скидывать стили для всех сайтов. CSS раздуется до неимоверных размеров.
input {
  background-color: transparent !important;
  border: 1px solid #0de !important;
  ...
}


Если же Вы наоткуп отдаете стили, чтобы интеграторы с этим вопросом справлялись сами, то кажется, что им это не нужно. Ведь это нужно иметь штатного верстальщика и не всем он нужен. Хочется просто подключить JS и чтобы работало.

В общем, сам я больше за iframe только из-за того, что отгребу от CSS.
Ответ написан
iframe нужно использовать для вставки кода стороннего сайта, как минимум, по причине безопасности пользователей своего сайта. Если что-то сломается или будут проблемы безопасности во вставке кода, то это не коснется твоего сайта.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
KorniloFF
@KorniloFF Куратор тега JavaScript
Работаю по font-end / JS
ИМХО, тимлид прав, проблем никаких не должно быть, в случае строгой инкапсулляции всего JS-кода. Если нужно взаимодействие с внешним кодом - можно предоставить единую переменную для реализации какого-то клиентского API.

Проблемы могут быть при обработке входящих данных с неизвестных сайтов на сервере. Вот там нужно будет жёстко всё фильтровать.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы