You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Electron Forge+React+TS中如何正确调用GitHub公开API?

Electron Forge + React + TypeScript 渲染进程调用GitHub公开API解决方案

问题背景

使用Electron Forge + ReactJS + TypeScript技术栈,主进程中通过Octokit调用GitHub公开API(https://api.github.com/repos/nzhul/tic-tac-toe-online/releases/latest)正常,但在React渲染进程中执行相同代码时先后出现两个报错:

  1. 初始报错:CSP(内容安全策略)限制,未允许连接GitHub API域名
  2. 修改CSP后报错:GitHub的CORS策略不允许跨域请求携带X-GitHub-Api-Version自定义头

报错详情

初始CSP报错

Refused to connect to 'https://api.github.com/repos/nzhul/tic-tac-toe-online/releases/latest?owner=OWNER&repo=REPO'
because it violates the following Content Security Policy directive: "default-src 'self' 'unsafe-inline' data:".
Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.

修改CSP后的CORS报错

Access to fetch at 'https://api.github.com/repos/nzhul/tic-tac-toe-online/releases/latest?owner=OWNER&repo=REPO' from origin 'http://localhost:3000' has been blocked by CORS policy:
Request header field x-github-api-version is not allowed by Access-Control-Allow-Headers in preflight response.

解决方案

方案一:主进程IPC转发请求(推荐)

Electron主进程不受浏览器CORS限制,通过IPC(进程间通信)让渲染进程委托主进程发起API请求,彻底规避CORS和CSP问题:

1. 主进程(main.ts)注册IPC handler

将Octokit请求逻辑移到主进程,并通过ipcMain.handle暴露给渲染进程:

import { app, BrowserWindow, ipcMain } from 'electron';
import { Octokit } from '@octokit/rest';

// ...其他主进程代码

// 注册IPC方法,处理渲染进程的API请求
ipcMain.handle('get-latest-release', async () => {
  const octokit = new Octokit();
  try {
    const response = await octokit.request("GET /repos/nzhul/tic-tac-toe-online/releases/latest", {
      owner: "nzhul", // 替换为实际仓库所有者
      repo: "tic-tac-toe-online", // 替换为实际仓库名
      headers: {
        "X-GitHub-Api-Version": "2022-11-28",
      },
    });
    return response.data;
  } catch (error) {
    console.error('获取最新版本失败:', error);
    throw error; // 抛出错误让渲染进程处理
  }
});

2. 渲染进程(React组件)调用IPC方法

在React组件中使用ipcRenderer.invoke调用主进程的API:

import { ipcRenderer } from 'electron';
import { useEffect, useState } from 'react';

const ReleaseInfo = () => {
  const [releaseData, setReleaseData] = useState<any>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const fetchRelease = async () => {
      try {
        const data = await ipcRenderer.invoke('get-latest-release');
        setReleaseData(data);
      } catch (err) {
        setError('获取版本信息失败');
        console.error(err);
      }
    };
    fetchRelease();
  }, []);

  return (
    <div>
      {releaseData ? (
        <div>
          <h3>最新版本: {releaseData.name}</h3>
          <p>发布时间: {releaseData.published_at}</p>
        </div>
      ) : error ? (
        <p>{error}</p>
      ) : (
        <p>加载中...</p>
      )}
    </div>
  );
};

export default ReleaseInfo;

方案二:调整渲染进程请求配置(临时/非推荐)

如果必须在渲染进程直接请求,需修改两个点:

  1. 移除X-GitHub-Api-Version自定义头(GitHub公开API默认使用最新版本,若需指定版本仍建议用方案一)
  2. 收紧CSP配置,精准允许GitHub API域名,避免过度开放:

修改forge.config.ts的CSP配置

export default {
  // ...其他配置
  plugins: [
    {
      name: '@electron-forge/plugin-react',
      config: {
        devContentSecurityPolicy: "default-src 'self' 'unsafe-inline' data:; connect-src 'self' https://api.github.com;",
      },
    },
    // ...其他插件
  ],
};

渲染进程修改后的Octokit代码

const getRepoInfo = async () => {
  const octokit = new Octokit();
  try {
    const response = await octokit.request("GET /repos/nzhul/tic-tac-toe-online/releases/latest", {
      owner: "nzhul",
      repo: "tic-tac-toe-online",
      // 移除X-GitHub-Api-Version头
    });
    return response;
  } catch (error) {
    console.error('请求失败:', error);
    throw error;
  }
};

内容的提问来源于stack exchange,提问作者Dobromir Ivanov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:14:57