Страницы: 1
Добрый день.
Разрабатываю аддон к Firefox. Для его корректной работы требуется получить в строковую переменную оригинальный исходный код открытой страницы - не содержимое body как во многих примерах, а целиком - с doctype, head.
Нашел вот такую реализацию:
var cont = window.getBrowser().contentDocument; var ser = new XMLSerializer(); var st = ser.serializeToString(cont);
На первый взгляд она работает правильно, но это не так. К примеру, если такому обработчику подсунуть заведомо некорректную страницу, в которой, допустим, нет <body> и <html>, он их создаст искусственно! И хотя эти тэги будут пустыми, получится, что оригинальная страница не соответствует результату. А одна из задач аддона получить код абсолютно такой как в оригинале.
Также мне посоветовали копать в сторону view-source. Я смотрел готовые реализации, но они не устраивают тем, что фактически мы запрашиваем страницу заново и при определенных условиях можно получить совсем не тот контент, что в ранее открытой странице
Отсутствует
Как тут не подходит? Вроде бы, заново не запрашивается.
Прошлое – это локомотив, который тянет за собой будущее. Бывает, что это прошлое вдобавок чужое. Ты едешь спиной вперед и видишь только то, что уже исчезло. А чтобы сойти с поезда, нужен билет. Ты держишь его в руках. Но кому ты его предъявишь?
Виктор Пелевин. Желтая стрела
Отсутствует
Как тут не подходит? Вроде бы, заново не запрашивается.
Спасибо за ответ и пример. Тем не менее вот этот участок кода
как раз и делает запрос (хоть и через AJAX). Как я понимаю, браузер подставляет результат из кэша, т.е. фактически этот прием работает. Но вот есть две предположительных ситуации, в которых он будет давать сбой:
1. Страница не кэширована
2. Содержимое страницы поменялось скриптом, находящимся на этой же странице
Отсутствует
Запрос-то будет уже по другой ссылке через протокол «view-source:» – точно так же как при вызове встроенной команды просмотра исходного кода.
В качестве альтернативы можно только обрабатывать загрузку всего подряд и сделать свой кэш для исходного кода всех страниц. А это как-то совсем не оптимально выходит.
Ну, или можно как-то получить доступ к кэшу этого view-source.
2. Содержимое страницы поменялось скриптом, находящимся на этой же странице
Я думаю, с этим ничего не сделать – скрипты работают с уже преобразованным внутренним представлением, куда уже добавились <html>, <body> и <tbody> у таблиц.
Прошлое – это локомотив, который тянет за собой будущее. Бывает, что это прошлое вдобавок чужое. Ты едешь спиной вперед и видишь только то, что уже исчезло. А чтобы сойти с поезда, нужен билет. Ты держишь его в руках. Но кому ты его предъявишь?
Виктор Пелевин. Желтая стрела
Отсутствует
Запрос-то будет уже по другой ссылке через протокол «view-source:» – точно так же как при вызове встроенной команды просмотра исходного кода.
Вот мне не до конца понятен этот момент. С одной стороны «view-source:» при открытой странице с тем же адресом как-будто обращается к локальной копии (кэшу?) этой страницы. С другой - можно сразу зайти на нужную страницу через «view-source:». В этом случае браузер ее открывает заново
Я думаю, с этим ничего не сделать – скрипты работают с уже преобразованным внутренним представлением, куда уже добавились <html>, <body> и <tbody> у таблиц.
А вот инспектор кода же как-то работает с измененными данными. Значит в браузер встроен еще какой-то хитрый механизм, к которому нет доступа из аддонов...
Отсутствует
А вот инспектор кода же как-то работает с измененными данными. Значит в браузер встроен еще какой-то хитрый механизм, к которому нет доступа из аддонов...
Ну так там и получится как раз вот это:
К примеру, если такому обработчику подсунуть заведомо некорректную страницу, в которой, допустим, нет <body> и <html>, он их создаст искусственно!
Добавлено 21-05-2013 10:23:49
В принципе, можно попробовать что-нибудь извлечь из
BrowserViewSourceOfDocument() -> gViewSourceUtils.viewSource() -> gViewSourceUtils.openInInternalViewer()
-> chrome://global/content/viewSource.js viewSource()
try { if (typeof(arg) == "object" && arg != null) { // Load the page using the page descriptor rather than the URL. // This allows the content to be fetched from the cache (if // possible) rather than the network... gPageLoader.loadPage(arg, gPageLoader.DISPLAY_AS_SOURCE); // The content was successfully loaded. loadFromURL = false; // Record the page load in the session history so <back> will work. var shEntrySource = arg.QueryInterface(Ci.nsISHEntry); var shEntry = Cc["@mozilla.org/browser/session-history-entry;1"].createInstance(Ci.nsISHEntry); shEntry.setURI(makeURI(viewSrcUrl, null, null)); shEntry.setTitle(viewSrcUrl); shEntry.loadType = Ci.nsIDocShellLoadInfo.loadHistory; shEntry.cacheKey = shEntrySource.cacheKey; gBrowser.sessionHistory .QueryInterface(Ci.nsISHistoryInternal) .addEntry(shEntry, true); } } catch(ex) { // Ignore the failure. The content will be loaded via the URL // that was supplied in arg[0]. }
Отредактировано Infocatcher (21-05-2013 10:24:32)
Прошлое – это локомотив, который тянет за собой будущее. Бывает, что это прошлое вдобавок чужое. Ты едешь спиной вперед и видишь только то, что уже исчезло. А чтобы сойти с поезда, нужен билет. Ты держишь его в руках. Но кому ты его предъявишь?
Виктор Пелевин. Желтая стрела
Отсутствует
Infocatcher, спасибо, буду пробовать. Также стараюсь точно выяснить при каких условиях каждый механизм будет глючить
Отсутствует
Страницы: 1