无法读取Javascript文件Electron JS中未定义的属性“ join” [英] Cannot read property 'join' of undefined in Javascript file Electron JS

查看:151
本文介绍了无法读取Javascript文件Electron JS中未定义的属性“ join”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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.

我遇到的问题是说加入是未定义的:

The issue I am having is that it is saying that join is undefined:


weather.js:9未捕获的TypeError:无法读取
未定义
的属性 join 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,'/../引擎/'),似乎是令人讨厌的代码。

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?

谢谢。

推荐答案

问题

因为默认情况下在窗口中禁用电子5 nodeIntegration 。由于普通的浏览器API不知道需要加入,因此在尝试时会出错。

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

您可以启用 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。该值应该是脚本的绝对文件路径。关闭节点集成后,预加载脚本可以将节点全局符号重新引入全局范围。

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.

示例

以下是示例应用程序,这会打开一个带有按钮的窗口,该按钮使用电子对话框选择文件。这在禁用 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中未定义的属性“ join”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆