电子环境桥返回未定义

发布于 2025-01-26 07:43:40 字数 2004 浏览 6 评论 0原文

我有这4个项目文件:

main.js
preload.js
renderer.js
index.html

节点:17.4.0 电子:18.2.0

我正在尝试在文件系统上打开文本文件,该文件是由 Renderer.js 的点击事件触发的,然后将文本文件的内容加载到< div> index.html中的标签。

main.js

const {app, BrowserWindow, ipcMain} = require("electron");
const path = require("path");
const fs = require("fs");

const createWindow = () => {
    // Create the browser window.
    const mainWindow = new BrowserWindow({
         webPreferences: {
            preload: path.join(__dirname, 'preload.js'),
            contextIsolation: true,
            nodeIntegration: false
         }
    });
    mainWindow.loadFile(path.join(__dirname, "index.html"));

    // Open the DevTools.
    mainWindow.webContents.openDevTools();
};

app.on("ready", () => {
    createWindow();

    app.on("activate", () => {
        if (BrowserWindow.getAllWindows().length === 0) createWindow();
    });
});


function openFile(){
    fs.readFile("logs.txt", "utf8", (err, data) => {
        if (err) {
            console.error(err);
            return "Error Loading Log File";
        }
        console.log(data);
        return data;
    });
}

ipcMain.handle("channel-load-file", openFile);

PRELOAD.JS

const {contextBridge, ipcRenderer} = require("electron");

contextBridge.exposeInMainWorld("electronAPI", {
    loadFile: () => ipcRenderer.invoke("channel-load-file")
});

Renderer.js

const btn = document.querySelector("#btn");
btn.addEventListener("click", e => {
   let data = window.electronAPI.loadFile();
   document.getElementById("main-content").innerText = data;
});

我肯定可以在console.log(数据)内看到日志文件的内容 在 main.js

; 未定义。

我相信我错过了一个关键的步骤:preload.jsrenderer.js

有人看到事件链丢失的位置吗?

(我对我的流程的任何改进都非常开放)

I've got these 4 project files:

main.js
preload.js
renderer.js
index.html

Node: 17.4.0
Electron: 18.2.0

I'm attempting to open a text file on my filesystem, triggered by a click event from renderer.js - then load the text file's contents into a <div> tag in index.html.

main.js

const {app, BrowserWindow, ipcMain} = require("electron");
const path = require("path");
const fs = require("fs");

const createWindow = () => {
    // Create the browser window.
    const mainWindow = new BrowserWindow({
         webPreferences: {
            preload: path.join(__dirname, 'preload.js'),
            contextIsolation: true,
            nodeIntegration: false
         }
    });
    mainWindow.loadFile(path.join(__dirname, "index.html"));

    // Open the DevTools.
    mainWindow.webContents.openDevTools();
};

app.on("ready", () => {
    createWindow();

    app.on("activate", () => {
        if (BrowserWindow.getAllWindows().length === 0) createWindow();
    });
});


function openFile(){
    fs.readFile("logs.txt", "utf8", (err, data) => {
        if (err) {
            console.error(err);
            return "Error Loading Log File";
        }
        console.log(data);
        return data;
    });
}

ipcMain.handle("channel-load-file", openFile);

preload.js

const {contextBridge, ipcRenderer} = require("electron");

contextBridge.exposeInMainWorld("electronAPI", {
    loadFile: () => ipcRenderer.invoke("channel-load-file")
});

renderer.js

const btn = document.querySelector("#btn");
btn.addEventListener("click", e => {
   let data = window.electronAPI.loadFile();
   document.getElementById("main-content").innerText = data;
});

I can definitely see the contents of the Log file inside console.log(data); in the main.js

But, the <div id="main-content"></div> gets populated with undefined.

I believe I'm missing some crucial step within either: preload.js or renderer.js

Anyone see where the chain of events is getting lost?

(I'm very open to any improvements to my flow)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ぃ双果 2025-02-02 07:43:40

插入console.log()在下面的代码中指示handle content是在openfile具有之前执行的
有机会返回结果。

main.js(主进程)

function openFile() {
    fs.readFile("logs.txt", "utf-8", (err, data) => {
        if (err) {
            console.error(err);
            return "Error Loading Log File";
        }

        console.log('openFile: ' + data); // Testing

        return data;
    });
}

ipcMain.handle('channel-load-file', () => {
    let result = openFile();

    console.log('handle: ' + result); // Testing

    return result;
})

console.log()结果是...

handle: undefined
openFile: File content...

要解决此问题,让我们从一个回到承诺,因此我们可以在handle> handle中等待等待。

由于handle正在处理承诺,让我们使用句法糖async等待 ,以便于实现。

main.js(主过程)

function openFile() {
    return new Promise((resolve, reject) => {
        fs.readFile("logs.txt", "utf-8", (error, data) => {
            if (error) {
                console.log('reject: ' + error); // Testing
                reject(error);
            } else {
                console.log('resolve: ' + data); // Testing
                resolve(data)
            }
        });
    });
}

ipcMain.handle('channel-load-file', async (event, message) => {
    return await openFile()
        .then((data) => {
            console.log('handle: ' + data); // Testing
            return data;
        })
        .catch((error) => {
            console.log('handle error: ' + error); // Testing
            return 'Error Loading Log File';
        })
});

最后,让我们修改我们在index.html文件中检索data的方式。

PS:让我们还将.toString()添加到返回的data(可以确保)。

index.html(渲染过程)

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Electron Test</title>
        <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';"/>
    </head>

    <body>
        <div id="main-content"></div>

        <input type="button" id="button" value="Load File">
    </body>

    <script>
        document.getElementById('button').addEventListener('click', () => {
            window.electronAPI.loadFile()
                .then((data) => {
                    console.log(data); // Testing
                    document.getElementById("main-content").innerText = data.toString();
                });
        })
    </script>
</html>

Inserting console.log()'s in the code below indicates that the handle content is executed before openFile has
a chance to return a result.

main.js (main process)

function openFile() {
    fs.readFile("logs.txt", "utf-8", (err, data) => {
        if (err) {
            console.error(err);
            return "Error Loading Log File";
        }

        console.log('openFile: ' + data); // Testing

        return data;
    });
}

ipcMain.handle('channel-load-file', () => {
    let result = openFile();

    console.log('handle: ' + result); // Testing

    return result;
})

The console.log() results are...

handle: undefined
openFile: File content...

To fix this, let's change fs.readFile from a callback to a promise, so we can await for it in the handle.

As the handle is dealing with a promise, let's use the syntactic sugar async and await for easier implementation.

main.js (main process)

function openFile() {
    return new Promise((resolve, reject) => {
        fs.readFile("logs.txt", "utf-8", (error, data) => {
            if (error) {
                console.log('reject: ' + error); // Testing
                reject(error);
            } else {
                console.log('resolve: ' + data); // Testing
                resolve(data)
            }
        });
    });
}

ipcMain.handle('channel-load-file', async (event, message) => {
    return await openFile()
        .then((data) => {
            console.log('handle: ' + data); // Testing
            return data;
        })
        .catch((error) => {
            console.log('handle error: ' + error); // Testing
            return 'Error Loading Log File';
        })
});

Lastly, let's modify the way we retrieve the data in the index.html file.

PS: Let's also add .toString() to the returned data (just to be sure).

index.html (render process)

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Electron Test</title>
        <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';"/>
    </head>

    <body>
        <div id="main-content"></div>

        <input type="button" id="button" value="Load File">
    </body>

    <script>
        document.getElementById('button').addEventListener('click', () => {
            window.electronAPI.loadFile()
                .then((data) => {
                    console.log(data); // Testing
                    document.getElementById("main-content").innerText = data.toString();
                });
        })
    </script>
</html>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文