Как я могу получить доступ к содержимому <webview> (NW.JS/Electron)?

Я использовал <webview> тег в NW.JS, чтобы заменить с помощью iFrames (по соображениям производительности), но не смог найти более подробную информацию ни о документах NWJS, ни о фактической <webview> документы

Я просто хотел получить document.title изнутри <webview> и отправьте это обратно в основной процесс.

1 ответ

Ограниченная документация по Webview (доступная через NWJS/Electron) делает очень трудным понимание того, как делать основные вещи, такие как получение доступа к / изнутри Webview, так что, надеюсь, это поможет.

К вашему сведению - в контексте Электрон и NWJS, <webview> Тег позволяет отображать веб-сайты (например, iframe), с тем преимуществом, что он запускается в отдельном процессе. Это намного лучше для производительности, чем куча фреймов. <webview> содержит стандартный HTML-документ, сложность которого, скажем, в iframe заключается в том, что он выполняется в отдельном процессе.

Основное решение для связи между основным процессом и внутри <webview> это использовать обычай Webview ContentWindow.postMessage() метод. Это в значительной степени основано на window.postMessage(), Используя postMessage() - конкретно отслеживая event.source - мы создаем коммуникационный мост между основным процессом и <webview>,

Как это работает (по крайней мере, один способ, который я нашел):

  1. Во-первых, свяжите EventListeners из основного процесса с <webview> и окно (чтобы прослушать позже сообщение изнутри <webview>)
  2. Когда <webview> элемент загружает URL, он запускает contentload()
  3. contentload() вставит EventListener в <webview> и настроить элементы данных /DOM, которые мы хотим получить изнутри <webview>,
  4. Однажды <webview> заканчивает загрузку, запускает loadstop()
  5. loadstop() отправит сообщение <webview> установить мост. Важно отметить, что здесь я использую webview.contentWindow.postMessage() вместо window.postMessage(),
  6. <webview> отвечает данными, которые мы настроили на шаге 1
  7. Когда основной процесс получает ответ обратно (через EventListener "message") от <webview>, это вызывает receiveHandshake()
  8. Внутри receiveHandshake() Теперь у вас есть доступ к данным, которые пришли из <webview>, Это может быть заголовок страницы или любой другой, который вы настроили в webviewInjectScript,
  9. Наконец я звоню removeListeners() чтобы удалить все EventListeners, которые мы настроили, но вы можете продолжать отправлять сообщения туда и обратно.
const webview = document.getElementById('your-webview-element');

// <webview> Content is loaded
function contentload() {
  // The following will be injected in the webview
  const webviewInjectScript = `
      var data = {
        title: document.title,
        url: window.location.href
      };

      function respond(event) {
        event.source.postMessage(data, '*');
      }

      window.addEventListener("message", respond, false);
  `;

  webview.executeScript({
    code: webviewInjectScript
  });
}

// <webview> Loading has finished
function loadstop() {
  webview.contentWindow.postMessage("Send me your data!", "*"); // Send a request to the webview
}

// Bind events
webview.addEventListener("contentload", contentload);
webview.addEventListener("loadstop", loadstop);
window.addEventListener("message", receiveHandshake, false); // Listen for response

function receiveHandshake(event) {
  // Data is accessible as event.data.*
  // This is the custom object that was injected during contentload()
  // i.e. event.data.title, event.data.url
  console.log(event.data)

  // Unbind EventListeners
  removeListeners();
}

// Remove all event listeners
function removeListeners() {
  webview.removeEventListener("loadstart", loadstart);
  webview.removeEventListener("contentload", contentload);
  webview.removeEventListener("loadstop", loadstop);
  window.removeEventListener("message", receiveHandshake);
}

(Примечание: протестировано только в NW.JS). Информацию о поддержке Electron в Webview смотрите здесь. Есть также другая тема об использовании IPC в Electron. Это не вариант для меня с NW.JS.

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