почему Chrome unsafeWindow trick не поддерживает переопределение отправки XMLHttpRequest?
Я хочу переопределить отправку XMLHttpRequest
, чтобы мой userscript знал, когда данные обновляются на странице через такой запрос. Мой код переопределения выглядит следующим образом:
var oldSend = unsafeWindow.XMLHttpRequest.prototype.send;
unsafeWindow.XMLHttpRequest.prototype.send = function(){
console.log("notified of XHR update");
oldSend.apply(this, arguments);
}
Если я введу это в страницу (без ссылок на unsafeWindow
), это работает нормально,но я хотел бы получить эту работу из области userscript. unsafeWindow
работает для этого в Firefox, но не в Chrome. Поэтому я ухватился за ловкий трюк Брока Адамса, чтобы создать рабочий unsafeWindow
в Chrome :
var bGreasemonkeyServiceDefined = false;
try {
if (typeof Components.interfaces.gmIGreasemonkeyService === "object") {
bGreasemonkeyServiceDefined = true;
}
}
catch (err) {
//Ignore.
}
if ( typeof unsafeWindow === "undefined" || ! bGreasemonkeyServiceDefined) {
unsafeWindow = ( function () {
var dummyElem = document.createElement('p');
dummyElem.setAttribute ('onclick', 'return window;');
return dummyElem.onclick ();
} ) ();
}
Однако, когда я совместить эти два ничего не получится. Все это работает вставлено в консоль, но нет ни ошибки, ни вывода при запуске этого из userscript. Я делаю что-то не так или, возможно, это за пределами возможностей этого трюка?
Хм, просто попробовал что-то попроще, например: unsafeWindow.document.title = 'testing';
и это тоже не работает, так что, возможно, это не специфично для XMLHttpRequest
.
Я пытаюсь избежать инъекции в страницу, если это вообще возможно.
1 ответ:
Это:
/*--- Create a proper unsafeWindow object on browsers where it doesn't exist (Chrome, mainly). Chrome now defines unsafeWindow, but does not give it the same access to a page's javascript that a properly unsafe, unsafeWindow has. This code remedies that. */ var bGreasemonkeyServiceDefined = false; try { if (typeof Components.interfaces.gmIGreasemonkeyService === "object") { bGreasemonkeyServiceDefined = true; } } catch (err) { //Ignore. } if ( typeof unsafeWindow === "undefined" || ! bGreasemonkeyServiceDefined) { unsafeWindow = ( function () { var dummyElem = document.createElement('p'); dummyElem.setAttribute ('onclick', 'return window;'); return dummyElem.onclick (); } ) (); }
Далее следует:
unsafeWindow.document.title = 'testing';
Отлично работает с моими тестовыми пользовательскими текстами.
Они также работают в соответствии с трюком
unsafeWindow
:unsafeWindow.foo = function () { console.log ("In foo()."); }; unsafeWindow.alert = function (s) { console.log ("Alert: ", s); };
(на странице, где был запущен скрипт, ввод
foo()
в консоль дает: " In foo().".alert()
не генерирует всплывающее окно,а выводит его на консоль.)Я не знаю, почему (пока) это переопределение
XMLHttpRequest.prototype.send
не работает так из пользовательского кода Chrome, но я не рекомендую подходunsafeWindow
для во всяком случае, так.введите код переопределения. Используйте postMessage () (который также работает в Chrome) для связи между областью страницы и областью сценария, если вы не можете (или не можете) ввести весь сценарий.