For example, here is a simple BrowserWindow
with appropriate security settings except for webviewTag: true
which is necessary for this project.
let webPrefs = {
plugins: false,
nodeIntegration: false,
nodeIntegrationInWorker: false,
webviewTag: true,
sandbox: true,
enableRemoteModule: false,
contextIsolation: true,
disableBlinkFeatures: "Auxclick",
webSecurity: true
};
let winOpts = {
...
show: true,
webPreferences: webPrefs
};
...
win = new BrowserWindow(winOpts);
const view = new BrowserView(winOpts);
win.setBrowserView(view);
...
view.webContents.loadURL("https://example.com").then(result => {
....
});
Suppose that the example.com
website contains <form>
with several <input>
fields.
Users will type text on these <input>
fields.
I want to extract the 'manually filled' text from those <input>
fields.
The webpage is not mine and thus cannot modify the website.
webContents.executeJavaScript()
can be a start point, but couldn't find how to 'extract' the value itself to the main
process.
(filling the forms from main process can be done by using the function above.)
How can I achieve this?
in your main import ipcMain
from electron
like this
const { ipcMain, app, BrowserWindow,BrowserView } = require("electron");
in your webPrefs
add preload file. for example
let webPrefs = {
plugins: false,
nodeIntegration: false,
nodeIntegrationInWorker: false,
webviewTag: true,
sandbox: true,
enableRemoteModule: false,
contextIsolation: true,
disableBlinkFeatures: "Auxclick",
webSecurity: true,
preload:"./preload.js"
};
create a new preload file and named it "preload.js". of course you can name it and to anything you want just make sure you set the correct filename in the preload
above.
this file is like a bridge between you webview and main process. A preload script runs before the renderer process is loaded, and has access to both renderer globals (e.g. window and document) and a Node.js environment.
put the following code in preload.js
file
const { ipcRenderer } = require("electron");
window.addEventListener("input", (e) => {
//dom_element_id = the id of input element you want
if (e.target.id === "dom_element_id")
ipcRenderer.invoke("INPUT_OCCURED", e.target.value);
});
now go back to your main file and and for example you can add
win.loadURL("https://www.example.com");
ipcMain.handle("INPUT_OCCURED", (event, data) => {
console.log(data);
});
that all the code you need. now with some more explanation.
the preload file is loaded before the webview content and can run anything you want. its also had access to node stuff. what we do it communicate between the preload and the main using ipc. we adding a global listener in the preload which listing to all input event. then he checks and if the id is match the dom_element_id
its send the dom element value to main. the main got the event data in INPUT_OCCURED
he listing on
the reason i add a global listener instead of get the element and add listener to him is just for simplicity of the example