"Chrome Apps" webview.executeScript доступ к гостевым глобальным переменным
Я могу получить доступ к HTML-интерфейсу приложения Chrome с помощью:
webview.executeScript(
{code: 'document.documentElement.innerHTML'},
function(results) {
// results[0] would have the webview's innerHTML.
});
Но я бы хотел получить значение глобальных переменных в гостевой системе следующим образом:
webview.executeScript(
{code: 'window.globalVar'},
function(results) {
// results[0] should have the webview's value of "globalVar".
});
Как я могу это сделать?
2 ответа
Ответ, чтобы суммировать необходимые шаги.
1) Вы вводите скрипт контента с webview.executeScript()
во встроенную страницу.
2) Поскольку страница настоящая window
изолирован, вам нужен скрипт уровня страницы для доступа к нему. Вы вводите это с <script>
пометить как обсуждено здесь.
3) скрипт уровня страницы может получить доступ к window
объект, но не может общаться со скриптом приложения. Однако он может запускать пользовательское событие DOM, которое может перехватить скрипт содержимого. Обсуждено здесь.
4) Наконец, из скрипта контента вам нужно отправить сообщение вашему скрипту приложения. Сценарий содержимого вызывает chrome.runtime.sendMessage
в то время как скрипт приложения слушает с chrome.runtime.onMessage
,chrome.runtime.sendMessage
Похоже, что он недоступен для сценариев с веб-контентом, добавленных с webview.executeScript()
, Обходной путь должен использовать postMessage
как описано здесь.
Это что-то вроде луковой структуры, поэтому вам нужно 2 шага "внутрь" и 2 шага "снаружи". Вы не можете сделать это в возвращаемом значении, которое передается executeScript
обратный вызов, поскольку хотя бы один из шагов "out" будет асинхронным.
Вы можете внедрить скрипт, который вставляет узел DOM со значением глобальной переменной. Затем вы возвращаете innerHTML этого узла и сразу получаете свое значение, не используя обратный вызов:
var code = "script = document.createElement('script'); script.text=\"var n=document.createElement('span');n.style.display='none';n.id='my-id';n.innerHTML=window.globalVar;document.body.appendChild(n)\"; document.head.appendChild(script);document.getElementById('my-id').innerHTML"
webview.executeScript(
{code: code},
function(results) {
console.log(results[0]);
});
Просто используйте идентификатор для узла DOM, который не используется, и все будет в порядке. Меня устраивает.