>Форум Mozilla Россия http://forum.mozilla-russia.org/index.php >Разработка http://forum.mozilla-russia.org/viewforum.php?id=18 >Перехват загрузки картинок(FF Extension) http://forum.mozilla-russia.org/viewtopic.php?id=12681 |
abevziuk > 22-09-2006 18:01:41 |
Здравствуйте! Выделить код Код:var MyClass = { .... doLoad: function(e) { dump("\n!DOMContentLoaded!\n"); var doc = e.originalTarget; var images = doc.getElementsByTagName("img"); for(i=0; i < images.length; i++) { images[i].src="http://127.0.0.1/1.gif"; } }, } window.addEventListener("DOMContentLoaded", MyClass.doLoad, false); ... Но проблема в том, что картинки загружаются раньше, чем функция MyClass.doLoad получает управление, т.е. сначала отображаются оригинальные картинки(страница продолжает загружатся), а только потом они подменяются моей. Смотрю в исходник AdBlock и что называется - вижу фигу. Подскажите, хоть в какую сторону смотреть ? |
Владимиp Палант > 23-09-2006 05:22:13 |
Да уж, не слишком просто... Смотреть надо в сторону nsIContentPolicy. Вы должны написать XPCOM-компоненту, которая будет реализовывать этот интерфейс и зарегистрируется в категории content-policy - тогда вы сможете заблокировать загрузку картинки. А потом надо еще подменить ее на другую. Картинки реализуют интерфейс nsIImageLoadingContent, там можно вызвать метод loadImageWithChannel, чтобы подсунуть ей другое соединение. Сразу предупреждаю: все эти манипуляции с картинкой прямо в shouldLoad делать нельзя, будут страшные глюки. Для подобных изменений всегде нужно устанавливать таймаут на 0 мс. BlockSite работает проще, регистрирует observer'а для сообщения http-on-modify-request. Вот только я не нашел способа перенаправить запрос из такого observer'а. |
Dionys > 23-09-2006 10:12:56 |
Владимиp Палант
Для решения задачи в таком обсервере достаточно заменить URI запроса. Но тут встаёт вопрос, как определить, что запрашивается картинка. |
Dark-Demon > 25-09-2006 11:27:05 |
Dionys, по расширению? |
INFOMAN > 25-09-2006 12:37:01 |
Dark-Demon, не пойдёт - иногда картинки генерятся динамически скриптами и, соответственно, имеют расширение .php |
Al_H > 25-09-2006 13:24:56 |
В отклике сервера будет стоять что-то вроде Content-Type: image/png - проблема в том, что если расширение php, браузер не знает, какой тип запрашивать, и истину мы узнаем только по отклику сервера. |
abevziuk > 25-09-2006 18:46:55 |
Спасибо за ответы
Не совсем понятно, Вы предлагаете заменять прямо в Subject: Выделить код Код:var observer = { observe: function(subject, topic, data) { ..... subject.URI.spec = "127.0.0.1.gif"; ... } или через Выделить код Код:var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel); httpChannel.setRequestHeader ? первый способ влобовую не работает, со вторым пока не успел разобратся. Также в BlockSite было замеченно, что у subject вызывается метод cancel Хотя в документации по nsISupports(http://www.xulplanet.com/references/xpc … sISupports) (http://developer.mozilla.org/en/docs/nsISupports), не найдено, или я не туда смотрю ? |
Dionys > 26-09-2006 09:58:50 |
Долно работать такое: Выделить код Код:observe: function(subject, topic, data) { subject.QueryInterface(Components.interfaces.nsIHttpChannel); subject.URI.spec = "http://127.0.0.1/1.gif"; } |
abevziuk > 26-09-2006 15:18:44 |
Собственно говоря этот способ и не работает. В (http://xulplanet.mozdev.org/references/ … annel.html) и обозначено, что URI - read-only |
Dionys > 27-09-2006 09:36:56 |
Странно, у меня есть рабочее расширение, в котором используется именно этот способ. Кроме того хоть URI и read-only, но URI.spec - изменяемое свойство. |
abevziuk > 27-09-2006 12:59:56 |
Вообщем-то да, оно изменяется, но картинка грузится с оригинального адреса. Временно сделал костыль ввиде отмены загрузки картинки, а затем прохождения по DOM и подмене своей(ну ооочень не хочется за xpcom браться) |
Владимиp Палант > 29-09-2006 16:39:39 |
Проблема не в том, чтобы определить, что загружается картинка - при загрузке картинки браузер посылает другой заголовок Accept. Но все эти штуки с изменением URI.spec я уже пробовал (этот код в BlockSite - мой), они не работают. Судя по всему, на стадии http-on-modify-request браузер уже определился, к какому серверу уйдет запрос, и менять можно уже только адрес внутри этого сервера. Поэтому я и сказал, что смотреть надо в стороны nsIContentPolicy. |