【问题标题】:How can I fix IPC error "Error invoking remote method, an object could not be cloned" in Electron?如何修复 Electron 中的 IPC 错误“调用远程方法时出错,无法克隆对象”?
【发布时间】:2021-05-02 02:53:18
【问题描述】:

整个错误信息如下:

错误:调用远程方法“MY-IPC-CHANNEL”时出错:错误:一个对象 无法克隆。在 EventEmitter.o.invoke (electron/js2c/renderer_init.js:71)

electron/js2c/renderer_init.js:71 行不是我的原始代码行,而是编译后的代码行。

我正在尝试发送 POST 请求以获取我的 Google 访问令牌,以便我可以使用 Google Drive 的 API。目前,我一直在尝试通过向主进程提供我从 Google 获得的代码并使其向身份验证服务器发送 POST 请求来尝试在渲染器进程和主进程之间进行通信。我建立连接没有问题,但是当我在发送 HTTP 请求时尝试这样做时,出现上述错误。

// ******* MAIN *******
function exchangeCodeForAccessToken(code: string) {
    const clientID = "My Google client ID";
    const clientSecret = "My Google client secret";
    const body = {
      code: code,
      client_id: clientID,
      client_secret: clientSecret,
      redirect_uri: "http://localhost:4000",
      grant_type: "authorization_code",
    };
    const body2 = `code=${code}&
    client_id=${clientID}&
    client_secret=${clientSecret}&
    grant_type=authorization_code`;

  // return fetch("https://oauth2.googleapis.com/token", {
  //   method: "POST",
  //   body: body
  // });

    return axios.post("https://oauth2.googleapis.com/token", body);
}

这是主句柄:

// ******* MAIN *******
ipcMain.handle(
  OAUTH2_ACCESS_TOKEN_REQUEST_CHANNEL,
  async (event, code: string) => await exchangeCodeForAccessToken(code)
);

以及渲染器调用函数:

// ******* RENDERER *******
function exchangeCodeForAccessToken(code: string) {
  ipcRenderer.invoke(OAUTH2_ACCESS_TOKEN_REQUEST_CHANNEL, code).then((response) => {
    console.log(response);
  }).catch((error) => {
        //TODO Improve error handling
        console.log(error);
    });
}

我尝试通过 Electron 的 net 模块发送请求。我还尝试了electron-fetch 模块,它应该是Node fetch 模块的Electron 集成版本。最后我尝试了axios 模块,但它一直抛出同样的错误。我认为它与通过 IPC 进行对象序列化有关,但后来我尝试只使用该函数而不返回它的承诺,并且不断弹出相同的错误。这意味着错误不仅在返回 promise 时出现,而且在调用 HTTP 请求函数时出现。我还尝试使用请求的对象版本及其字符串版本发送请求,因此bodybody2

我不知道自己错过了什么,而且我非常接近将 Google 登录集成到我的桌面应用程序中。

【问题讨论】:

    标签: node.js http serialization electron ipc


    【解决方案1】:

    我认为它与通过 IPC 进行对象序列化有关,但后来我尝试只使用该函数而不返回它的承诺,并且不断弹出相同的错误。

    这是一个 IPC 错误。您将返回完整的响应对象,该对象可能包含一些带有方法和/或其他不可克隆值的属性。您需要确保返回的值可以被克隆并发送到渲染器,例如:

    ipcMain.handle(
      OAUTH2_ACCESS_TOKEN_REQUEST_CHANNEL,
      async (event, code) => {
        const response = await exchangeCodeForAccessToken(code);
        const {status, data} = response;
        return {status, data};
      }
    );
    

    我不确定您是如何调用该函数来尝试解决此问题的,但我只是在 Electron 中运行了它,它可以正常工作。

    编辑:假设 response 来自 fetch 调用(如果数据是 JSON,则使用 response.json()):

    ipcMain.handle(
      OAUTH2_ACCESS_TOKEN_REQUEST_CHANNEL,
      async (event, code) => {
        const response = await exchangeCodeForAccessToken(code);
        const data = await response.text();
        return data;
      }
    );
    

    【讨论】:

    • 你是救生员!非常感谢。
    • 您是否有任何提示如何使用 fetch 而不是 axios 做同样的事情?响应类型是一个 Response 对象,所以我不能解构它。
    • 当然,您只需要在响应中调用textjsonarrayBuffer(取决于您希望如何接收数据)。这会返回一个承诺,所以你需要等待它。我用一个例子更新了答案。
    • @szydlovski,对象可克隆的条件是什么?在这个 IPC 返回路径中返回对象的有效方法是什么?
    • @szydlovski,您如何在将多个参数发送到处理程序之前打包它们?以及它们是如何在函数头中作为处理程序中的参数接收的?
    猜你喜欢
    • 1970-01-01
    • 2018-12-21
    • 1970-01-01
    • 2020-12-22
    • 1970-01-01
    • 2021-02-13
    • 2015-01-30
    • 1970-01-01
    相关资源
    最近更新 更多