Используете iframe для песочницы? - PullRequest
1 голос
/ 16 июня 2011

Я занимаюсь разработкой системы, которая позволяет использовать JavaScript в виджетах.Чтобы обеспечить безопасность, я планирую помещать эти виджеты в «фреймы».Конечно, чтобы песочница была эффективной, iframe должен иметь домен, отличный от родительского документа.

Мне бы очень хотелось иметь возможность динамически генерировать iframe с кодом, подобным следующему:

template = '<html><body><script>/* user code */</script></body></html>'
src      = 'javascript: document.write("' + template + '")'
widget   = $('<iframe>').attr('src', src)

$('#container').append(widget)

... а затем обработать полученный iframe как междоменный из родительского окна.Возможно ли это, и если да, то как это будет сделано?

1 Ответ

3 голосов
/ 16 июня 2011

Хорошо, я думаю, что получаю то, что вам нужно, но это немного сложно.Вы хотите создать <iframe> и заполнить его пользовательской Javascript на стороне клиента, но клиентская песочница все еще есть?

Это довольно нестандартно.Обычно содержимое <iframe> генерируется на стороне сервера.Но здесь все идет.

Сначала немного предыстории: документы не могут получить доступ к содержимому любого документа, который не принадлежит тому же домену (включая поддомен) и порту.Но они могут изменить свой собственный домен безопасности, используя свойство document.domain.Так что вам нужно сделать это, чтобы повысить безопасность, а затем снова включить ее для запуска пользовательского скрипта.

Так что вы не сможете сделать это так, как вы указали, потому что если вы создаете <iframe> сJavascript src document.domain будет соответствовать родительскому фрейму.Это означает, что виджет будет иметь полный доступ ко всему.

Итак, вот как вы можете это сделать:

  1. Настройте два субдомена вашего основного домена.Давайте назовем их home.example.com и widgets.example.com.
  2. Создайте базовый HTML-файл на widgets.example.com и убедитесь, что он вызывает этот javascript: document.domain = "example.com";
  3. Теперь создайте свою страницу, которая будет содержатьвсе эти виджеты.Установите для него document.domain то же значение.
  4. Создайте все свои фреймы, загружая в него базовую HTML-страницу из widgets.example.com.
  5. Установите переменную внутри фрейма, содержащую шаблон пользователя.Пример: myFrame.contentWindow.foo = "template";
  6. Переключите document.domain в главном окне обратно на home.example.com, чтобы <iframe> s больше не имел доступа к родительскому фрейму
  7. Запуск шаблонаподстановка в кадре

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

Теперь, альтернативно, если виджет был заполнен на стороне сервера:

  1. Виджет хоста на widgets.example.com
  2. Страница хоста, содержащая виджет на home.example.com
  3. Готово

Но я предполагаю, что у вас есть причины для всего этогона стороне клиента.

Следующие логические темы: связь между фреймами и авторазмер.Но это на другой день.

Я ответил на ваш вопрос?Я надеюсь на это, потому что это было много печатать, и я не буду возражать против очков репутации, если вы проголосуете и примете мой ответ!;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...