Cómo utilizar correctamente las precargas y la ventana. api llama en electrones?

Estoy teniendo problemas para usar un renderizado. js file to write "api" calls from the render html page's javascript.

main.js nueva función BrowserWindow incluye:

    webPreferences: {
        nodeIntegration: false, // is default value after Electron v5
        contextIsolation: true, // protect against prototype pollution
        enableRemoteModule: false, // turn off remote
        preload: "preload.js" // use a preload script  
    },

preload.js:

const { ipcRenderer, contextBridge } = require('electron')

contextBridge.exposeInMainWorld(
    "api", {
        send: (channel, data) => {
            let validChannels = ["login"];
            if (validChannels.includes(channel)) {
                ipcRenderer.send(channel, data);
            }
        },
        receive: (channel, func) => {
            let validChannels = ["fromMain"];
            if (validChannels.includes(channel)) {
                ipcRenderer.on(channel, (event, ...args) => func(...args));
            }
        }
    }
);

contraseña Page.js linked in passwordPage.html:

document.getElementById("login").addEventListener('click', function() {
    window.api.send("login", "test");
})

error en consola de contraseña Página:

Uncaught TypeError: Cannot read property 'send' of undefined

Pregunta hecha hace 3 años, 4 meses, 29 días - Por algorithmwhiz


3 Respuestas:

  • Según docs:

    El valor debe ser el ruta de archivo absoluto al guión.

    Trate de usar `${__dirname}/preload.js` o algo igual.

    Respondida el Dec 18, 2020 a las 07:54 - por pixelpilot

    Votos positivos: 0 | Votos negativos: 0

  • El error "Uncaught TypeError: Cannot read property 'send' of undefined" se produce porque el objeto window.api no está definido en el contexto del renderizado de la página HTML.

    Para evitar este error, puedes asegurarte de que el script de preload.js se esté cargando correctamente antes de que se intente acceder a window.api desde el HTML.

    Aquí te dejo algunas sugerencias para solucionar este problema:

    • Asegúrate de que la ruta del archivo `preload.js` esté correcta en la configuración de la ventana del main.js. Verifica que el archivo preload.js se encuentre en la misma ubicación que el archivo html y que no haya errores en la ruta.
    • Asegúrate de que estás definiendo correctamente el objeto `api` en el archivo preload.js. Verifica que estás exportando las funciones send y receive correctamente.
    • Asegúrate de que el script preload.js se esté cargando antes de que se intente acceder a `window.api` desde el HTML. Una forma de hacer esto es utilizando la propiedad `preload` en la configuración de la ventana de BrowserWindow, como ya lo estás haciendo.

    Si después de revisar estos puntos sigues teniendo problemas, te recomendaría revisar la consola de desarrollador de Electron para verificar si hay algún otro error que pueda estar causando el problema.

    Espero que estas sugerencias te ayuden a resolver el problema. ¡Déjame saber si tienes alguna otra pregunta o inquietud!

    Respondida el Dec 19, 2020 a las 07:53 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El error que estás recibiendo se debe a que la propiedad api no está definida en el contexto de la página de contraseña. Esto se debe a que la configuración contextIsolation está establecida en true en webPreferences.

    Para resolver este problema, debes exponer la API al contexto de renderizado utilizando contextBridge. Aquí hay un ejemplo revisado del código preload.js:

    javascript
    const { ipcRenderer, contextBridge } = require('electron')
    
    contextBridge.exposeInMainWorld(
      'api', {
        send: (channel, data) => {
          let validChannels = ["login"];
          if (validChannels.includes(channel)) {
            ipcRenderer.send(channel, data);
          }
        },
        receive: (channel, func) => {
          let validChannels = ["fromMain"];
          if (validChannels.includes(channel)) {
            ipcRenderer.on(channel, (event, ...args) => func(...args));
          }
        }
      }
    );
    

    Este código expone un objeto api en el contexto de renderizado global que tiene funciones send y receive que se pueden utilizar para enviar y recibir mensajes a través de IPC.

    También debes asegurarte de que el archivo preload.js se cargue correctamente en el proceso de renderizado. Puedes hacerlo agregando la siguiente línea al final de tu archivo main.js:

    javascript
    mainWindow.loadFile('passwordPage.html')
    

    Respondida el Dec 19, 2020 a las 07:59 - por Gemini

    Votos positivos: 0 | Votos negativos: 0