无法读取 Javascript 文件 Electron JS 中未定义的属性“join”

iro*_*s7x 4 html python electron

我在 Electron JS 中有一个应用程序,它调用 python 函数来执行 python 脚本。当脚本执行时,它应该将数据发送回 Electron JS GUI 并显示它。

我遇到的问题是它说 join 未定义:

Weather.js:9未捕获类型错误:无法在HTMLButtonElement.onclick(weather.html:14)的get_weather(weather.js:9)读取未定义的属性“join”

这是我的 JavaScript 文件:

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 = "";
}
Run Code Online (Sandbox Code Playgroud)

“scriptPath : path.join(__dirname, '/../engine/'),”行似乎是有问题的代码。

我的gui.html文件如下:

<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>
Run Code Online (Sandbox Code Playgroud)

我需要修复哪些错误才能使其正常工作?

谢谢。

Rha*_*ene 7

问题

由于 Electron 5nodeIntegration在窗口中默认处于禁用状态。由于普通浏览器 API 不知道requireor join,因此当您尝试时会出现错误。

重新启用节点集成

您可以nodeIntegration再次启用,但由于某种原因它被禁用了。请务必阅读并理解电子安全教程

使用预加载脚本

另一种方法是使用预加载脚本。让我们看一下BrowserWindow 文档

创建新的浏览器窗口时,您可以添加多个选项。对于这种情况,我们需要以下webPreferences.preload选项:

指定将在页面中运行其他脚本之前加载的脚本。无论节点集成是打开还是关闭,该脚本始终可以访问节点 API。该值应该是脚本的绝对文件路径。当节点集成关闭时,预加载脚本可以将节点全局符号重新引入全局范围。

请注意,预加载脚本是在渲染器进程中运行的。

例子

以下是一个示例应用程序,它打开一个带有按钮的窗口,该按钮使用电子dialog来选择文件。这不适用于禁用的情况nodeIntegration,但由于我们的预加载脚本,我们重新引入dialog.showOpenDialog()了我们的窗口。

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"));
});

Run Code Online (Sandbox Code Playgroud)

预加载.js

const { dialog } = require("electron").remote;

window.mystuff = {
  selectFile
};

async function selectFile() {
  const files = await dialog.showOpenDialog({
    properties: ["openFile", "multiSelections"]
  });

  return files;
}
Run Code Online (Sandbox Code Playgroud)

索引.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>
Run Code Online (Sandbox Code Playgroud)

通过IPC发送事件

如果您不确定您的功能是否应该在窗口中公开,您还可以通过 发送事件ipcRenderer

预加载.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");
  });
}

Run Code Online (Sandbox Code Playgroud)

main.js中的附加部分


ipcMain.on("select-files", async () => {
  const files = await dialog.showOpenDialog({
    properties: ["openFile", "multiSelections"]
  });

  win.webContents.send("selected-files", files);
});

Run Code Online (Sandbox Code Playgroud)