問題描述
我在 Electron JS 中有一個應用程序,它調用 python 函數來執行 python 腳本.當腳本執行時,它應該將數據發送回 Electron JS GUI 并顯示它.
I have an application in Electron JS that is calling a python function to execute a python script. When the script executes it should send the data back to the Electron JS GUI and display it.
我遇到的問題是它說 join 是未定義的:
The issue I am having is that it is saying that join is undefined:
weather.js:9 Uncaught TypeError: Cannot read property 'join' of不明確的在 get_weather (weather.js:9)在 HTMLButtonElement.onclick (weather.html:14)
weather.js:9 Uncaught TypeError: Cannot read property 'join' of undefined at get_weather (weather.js:9) at HTMLButtonElement.onclick (weather.html:14)
這是我的 JavaScript 文件:
here is my JavaScript file:
let {PythonShell} = require('python-shell')
var path = require("path")
function get_weather() {
var city = document.getElementById("city").value
var options = {
scriptPath : path.join(__dirname, '/../engine/'),
args : [city]
}
let pyshell = new PythonShell('weatherApp.py', options);
pyshell.on('message', function(message) {
swal(message);
})
document.getElementById("city").value = "";
}
scriptPath : path.join(__dirname, '/../engine/')"這一行似乎是有問題的代碼.
The line "scriptPath : path.join(__dirname, '/../engine/')," seems to be the offending piece of code.
我的gui.html文件如下:
My gui.html file is as follows:
<html>
<head>
<title></title>
<meta charset="UTF-8">
</head>
<body>
<h1>Get your local weather ...</h1>
<br>
<br>
<label>Enter city name here: <label>
<input id="city" type = "text" placeholder="City">
<button type = "button" value="clickme" onclick="get_weather()">Get Weather</button>
<!--- <button class="btn btn-success" onclick="get_weather();">Go!</button> -->
<br>
<br>
<br>
<script src="/home/ironmantis7x/Documents/BSSLLC/projects/node_electron/electronDemoApps/guiApp/gui/linkers/weather.js"></script>
<p><button type="button"><a href="gui.html">Back to Main Page</a></button>
</body>
</html>
我需要修復哪些錯誤才能使其正常工作?
What error(s) do I need to fix to get this working correctly?
謝謝.
推薦答案
問題
自 Electron 5 起 nodeIntegration
默認在窗口中被禁用.由于普通瀏覽器 API 不知道 require
或 join
,因此在嘗試時會出錯.
Since Electron 5 nodeIntegration
is disabled by default in the window. Since normal browser API does not know require
or join
, you get errors when you try.
重新啟用節點集成
您可以再次啟用 nodeIntegration
,但由于某種原因它被禁用了.請務必閱讀并理解 電子安全教程.
You could enable nodeIntegration
again, but it was disabled for a reason. Be sure you read and understand the electron security tutorial.
使用預加載腳本
另一種方法是使用預加載腳本.讓我們看一下 BrowserWindow
文檔.
Another way is to use a preload script. Let's have a look at the BrowserWindow
documentation.
創建新的 BrowserWindow 時,您可以添加多個選項.對于這種情況,我們需要 webPreferences.preload
選項:
When creating a new BrowserWindow you can add several options. For this case we need the webPreferences.preload
option:
指定將在頁面中運行其他腳本之前加載的腳本.無論節點集成是打開還是關閉,此腳本都將始終可以訪問節點 API.該值應該是腳本的絕對文件路徑.關閉節點集成后,預加載腳本可以將 Node 全局符號重新引入全局范圍.
Specifies a script that will be loaded before other scripts run in the page. This script will always have access to node APIs no matter whether node integration is turned on or off. The value should be the absolute file path to the script. When node integration is turned off, the preload script can reintroduce Node global symbols back to the global scope.
請注意,預加載腳本是在渲染器進程中運行的.
Be aware that the preload script is run in the renderer process.
示例
以下是一個示例應用程序,它打開一個帶有按鈕的窗口,該按鈕使用電子 dialog
來選擇文件.這不適用于禁用的 nodeIntegration
,但由于我們的預加載腳本,我們將 dialog.showOpenDialog()
重新引入了我們的窗口.
Following is an example app, that opens a window with a button that uses the electron dialog
to select files. This would not work with disabled nodeIntegration
but thanks to our preload script, we reintroduced dialog.showOpenDialog()
to our window.
main.js
const { app, BrowserWindow } = require("electron");
const { join } = require("path");
let win;
app.on("ready", () => {
win = new BrowserWindow({
webPreferences: {
//this is the default since electron 5
nodeIntegration: false,
//here you load your preload script
preload: join(__dirname, "preload.js")
}
});
win.loadURL(join(__dirname, "index.html"));
});
preload.js
const { dialog } = require("electron").remote;
window.mystuff = {
selectFile
};
async function selectFile() {
const files = await dialog.showOpenDialog({
properties: ["openFile", "multiSelections"]
});
return files;
}
index.html
<html>
<body>
<main>
<button onclick="myFunction()">select file</button>
<ul id="foo"></ul>
</main>
<script>
async function myFunction() {
//the function provided by the preload script
const files = await window.mystuff.selectFile();
const list = document.getElementById("foo");
for (const file of files) {
const node = document.createElement("LI");
const textNode = document.createTextNode(file);
node.appendChild(textNode);
list.appendChild(node);
}
}
</script>
</body>
</html>
通過 IPC 發送事件
如果您不確定您的功能是否應該在窗口中顯示,您也可以通過 ipcRenderer
發送事件.
If you are unsure your functionality should be exposed in the window, you can also send events via ipcRenderer
.
preload.js
const { ipcRenderer } = require("electron");
window.mystuff = {
selectFile
};
function selectFile() {
return new Promise(resolve => {
ipcRenderer.on("selected-files", (e, files) => {
resolve(files);
});
ipcRenderer.send("select-files");
});
}
main.js中的附加部分
ipcMain.on("select-files", async () => {
const files = await dialog.showOpenDialog({
properties: ["openFile", "multiSelections"]
});
win.webContents.send("selected-files", files);
});
這篇關于無法讀取 Javascript 文件 Electron JS 中未定義的屬性“加入"的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!