"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, который не используется, и все будет в порядке. Меня устраивает.

Другие вопросы по тегам