Изменение Window.prototype.open способом, который не обнаружим / необратим - PullRequest
14 голосов
/ 11 июля 2011

Я ищу способы расширить блокировку всплывающих окон Firefox из расширения. Один из вариантов - заменить window.open() (или, скорее, Window.prototype.open()) на веб-странице функцией-оберткой. Важным требованием является то, что эта манипуляция не может быть обнаружена или отменена веб-страницей. Например, если я просто сделаю это:

Window.prototype.open = wrapper;

Веб-страница может легко отменить изменение, выполнив:

delete Window.prototype.open;

Вместо этого я могу использовать Object.defineProperty () для установки флагов дополнительных свойств:

Object.defineProperty(Window.prototype, "open", {value: wrapper, configurable: false});

Веб-страница больше не может отменить это изменение, но все же может обнаружить его: delete Window.prototype.open обычно изменяет значение Window.prototype.open (другой экземпляр той же функции, как кажется), здесь delete не будет иметь никакого эффекта совсем. Кроме того, Window.prototype.open = "test";delete Window.prototype.open; будет давать противоречивые результаты (разные в зависимости от того, указан ли для свойства флаг writable: false).

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

Ответы [ 4 ]

7 голосов
/ 14 сентября 2011

Вы можете попробовать использовать интерфейс nsIWindowWatcher для регистрации собственного создателя окна (nsIWindowCreator). Таким образом, вы можете контролировать, открывается ли новое окно, не затрагивая сам объект окна (и, таким образом, оставаясь невидимым для веб-сайтов).

Я не уверен, является ли ошибкой невозможность изменить реализацию window.open() без возможности ее обнаружения. Возможно, это просто не считается важным требованием для таких методов, как Object.defineProperty. Но, возможно, стоит оставить сообщение об ошибке, чтобы узнать, что другие думают о том, чтобы сделать этот вариант в будущем. В конце концов, блокировка рекламы - основной случай использования.

4 голосов
/ 04 октября 2011

В конце концов мне пришлось отказаться от использования прокси JavaScript для работы.Несмотря на то, что с некоторыми усилиями я могу создать оболочку для window.open(), которая будет вести себя точно так же, как оригинал ( ошибка 650299 должна быть рассмотрена), похоже, нет правильного способа заменить оригинал window.open() функция.Измененное свойство всегда будет вести себя иначе, чем оригинальное, что очень плохо.

Поэтому я решил использовать другой подход в качестве решения для блокировки всплывающих окон: прослушать content-document-global-created уведомление и посмотрите на предмет (новое окно), а также его открывашка.Окна с ненулевым открывателем являются всплывающими окнами.Можно посмотреть URL-адреса и решить, нужно ли блокировать всплывающее окно.Для блокировки необходимо вызвать window.stop() (останавливает все сетевые операции перед отправкой сетевых запросов) и window.close().Последний должен быть вызван асинхронно (с задержкой), поскольку в противном случае произойдет сбой, так как инициализация окна продолжается.Некоторые замечания об этом подходе:

  • Для всплывающих окон, открывающихся в новом окне, окно все равно будет отображаться, но сразу исчезнет.Это кажется неизбежным.
  • Для веб-страницы похоже, что ее всплывающее окно открылось, но было закрыто немедленно - это не то, как работает встроенный блокировщик всплывающих окон, больше похоже на внешнее всплывающее окноблокировка приложения.
  • Новые окна всегда сначала загружают about:blank, прежде чем перейти к их фактическому назначению.Для всплывающих окон одного и того же происхождения последнее не будет отправлять новое уведомление content-document-global-created, что вызывает сожаление.

В целом: не идеально, но можно использовать.И это очень просто, далеко не так много кода, необходимого для прокси JavaScript.

0 голосов
/ 16 сентября 2011

сегодня утром меня поразило: вы можете использовать Object.freeze(Window.prototype);! Тест показал, что методы, защищенные этой пушкой, могут быть удалены, но их легко обнаружить .


старый ответ:

Как насчет ES: Прокси Гармонии ? http://brendaneich.com/2010/11/proxy-inception/

Конечно, они нестабильны, но они работают в Firefox 4+, и вы не тот человек, который боится трудностей;)

0 голосов
/ 10 сентября 2011

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

Но вместо того, чтобы манипулировать свойствами объекта окна, почему бы не создать оболочку для объекта окна и локально переопределить окно оболочкой?

Пример:

// Copy window object to wraper
var wrapper = {};
for(prop in window) {
  wrapper[prop] = window[prop];
}

wrapper.open = function yourNewOpenFunction() {
  /// do your custom code here
}

(function fakeScope(window){
    window.open(); // this is wrapper.open
}(wrapper));

Кстати, это влияет только на тело внутри функции fakeScope () и не может применяться глобально.

...