Безопасна ли техника "песочницы iframe"?

Обновление: Поскольку вопрос остался без ответа, я немного меняю его. Комментарии к записи в блоге Дина, ссылка на которую приведена ниже, показывают, что эта техника не работает в Safari.

Теперь мой вопрос таков: работает ли описанная ниже техника* в современных браузерах, и, в частности, может ли кто-нибудь подтвердить, работает ли она в Safari?

Вот более свежий пост в блоге. В одном месте говорится:

Sandboxed natives ... поддерживается в различных браузерах, включая ... Safari 2.0+

... но позже говорится, что техника iframe "поддерживается всеми основными браузерами, кроме Safari", а показанный им запасной вариант включает в себя какие-то странные вещи с поддельными конструкторами и __proto__, которые кажутся немного халтурными.

Мне почти трудно поверить, что два разных окна могут иметь один и тот же, скажем, прототип Object.prototype. Что происходит с междоменными iframe? Если я изменяю прототипы в одном фрейме, будут ли изменены прототипы в другом фрейме? Это кажется очевидной проблемой безопасности. Кто-нибудь, пожалуйста, пролейте свет на эту ситуацию.

* Под "работать" я подразумеваю My.Object != Object, так что прототипы могут быть изменены в одном окне, не затрагивая другое.


Оригинальное сообщение

Я знаю, что об этом уже спрашивали, но у меня есть конкретное решение, и я хочу знать, обсуждался ли этот тип решения раньше, и где я могу узнать, насколько он надежен и хорошо принят.

Вопрос в том, как расширить нативные типы в javascript, не изменяя сами типы, так что простое изменение Array.prototype не подходит (возможно, в другом коде используется for..in с массивами). Создание поддельного конструктора, который возвращает родной массив с добавлением некоторых функций, тоже не кажется хорошим решением, лучше действительно расширить родные объекты. Но вы также не можете сделать обычное расширение в стиле javascript с фиктивным прототипом функции switcharoo с родными типами, потому что вы получите ошибки типа "push is not generic", когда попытаетесь вызвать родные функции.

Итак, решение, которое я имею в виду, работает следующим образом: создайте другое окно, добавьте функциональность к прототипам нативных конструкторов в этом окне, и используйте эти конструкторы в своей программе.

Этот пример расширяет Array как My.Array с функцией each и String как My.String с функцией alert.

    var My = (function(){

      // create an iframe to get a separate global scope
      var iframe = document.createElement('iframe');
      iframe.style.height = '0px';
      iframe.style.width = '0px';
      iframe.style.border = 'none';
      iframe.style.position = 'absolute';
      iframe.style.left = '-99999px';
      document.documentElement.appendChild(iframe);
      var My = iframe.contentWindow;

      My.String.prototype.alert = function(){
        alert(this);
      }

      My.Array.prototype.each = function(callback){
        for (var i=0, l=this.length; i

Опять же, мой вопрос в том, обсуждался ли этот подход раньше, как он называется, где я могу найти больше информации и т.д. Я хотел бы знать, есть ли более чистый способ получить другую глобальную область видимости без использования iframe, или возможно ли, что это не сработает по какой-то причине в некоторых javascript-движках, или если кто-то считает, что это особенно плохая идея, или что-то еще.


Обновление: я полагаю, что люди называют такие вещи iframe sandbox, не путать с атрибутом HTML5 iframe sandbox.

related:

http://dean.edwards.name/weblog/2006/11/hooray/

http://webreflection.blogspot.com/2008/03/javascript-arrayobject.html

17
задан Dagg Nabbit 10 December 2011 в 22:26
поделиться