Программный доступ к консоли браузера
Команды console.log() и иже с ней, предназначенные для вывода данных в консоль и добавления всяких 'свистелок' в выводе описаны 100500 раз. Это как бы обычно.
Нашел, как можно записывать консольные выхлопы в переменные, дабы использовать эти данные потом в коде.
Интересует, есть ли еще какие-то способы взаимодействия с консолью браузера из кода страницы и/или браузерного расширения (или еще как-то)? В частности, программно загнать в консоль текст команды/программы и выполнить их в консоли, не открывая саму консоль.
Вот например, команды xpath ($x("//*[@class='date']/text()");) выполняются сразу, в js коде нужно потанцевать с бубном немного. Возможно есть еще какие-то фичи, навскидку не помню.
Я понимаю, что такие манипуляции чреваты, ибо безопасность... Но все же. В расширениях ведь многое можно обходить.
В общем, кто что знает по данной теме, пишите. Буду рад любым подсказкам и идеям.
Ответы (1 шт):
Мы можем получить доступ не только к консоли, а вообще ко всему через DevTools.
Но сразу предупреждаю: Это нельзя сделать скрытно, при доступе к DevTools отображается такая "шляпа"(там где надпись "devtools" это имя расширения)
Пример перехвата консольных сообщений страницы и вывода в консоль расширения, та которая открывается через ссылку Отладка страниц фоновая страница:
app.js
const attached = new Set()
async function executeScript(tabId) {
console.log(`executeScript ${tabId}`)
await chrome.scripting.executeScript({
target: { tabId },
files: ['content.js']
})
}
void (async () => {
chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tabInfo) => {
if (!/^http/.test(tabInfo?.url ?? '')) return
console.log(`tabId:${tabId}, status:${changeInfo.status}`)
if (changeInfo.status !== 'complete') return
// Если обновили вкладку
if (attached.has(tabId)) {
await executeScript(tabId)
return
}
// Присоединяем вкладку к DevTools
chrome.debugger.attach({ tabId }, '1.3', async () => {
console.log(`attach ${tabId}`)
// Теперь можем прослушивать все события: Console|Network и т.п.
chrome.debugger.onEvent.addListener((debuggee, type, data) => {
if (debuggee?.tabId !== tabId || type !== 'Console.messageAdded') return
// Выводим сообщение консоли вкладки в devtools-консоль
console.log(`Сообщение цели отладки tabId${tabId}:`, data)
})
// Активируем Console
chrome.debugger.sendCommand({ tabId }, 'Console.enable', undefined, async (...data) => {
// Запустим на странице тестовый скрипт
// DevTools консоль будет отображать все сообщения страницы, в том числе и наш скрипт
await executeScript(tabId)
attached.add(tabId)
})
})
chrome.debugger.onDetach.addListener(({ tabId }) => {
console.log(`detached ${tabId}`)
if (tabId) attached.delete(tabId)
})
})
})()
content.js
console.log('Скрипт контента')
manifest.json
{
"manifest_version": 3,
"name": "devtools",
"description": "devtools",
"version": "0.1.0",
"author": "Хороший человек",
"action": {},
"background": {
"service_worker": "app.js"
},
"permissions": [
"tabs",
"scripting",
"debugger"
],
"host_permissions": [
"http://*/*",
"https://*/*"
]
}
Все три файла кидаем в один каталог и подключаем.
