Electron 中 HTML5 原生 API(如 FileReader、fetch、Canvas)可用,但需注意路径解析、拖拽启用及主进程桥接;禁用 nodeIntegration 时须通过 contextBridge + ipcRenderer 安全调用 Node.js 能力,打包后资源路径需用 protocol.handle 或 IPC 处理。

Electron 里 HTML5 的 File API 能用,但受限于 Node.js 环境隔离
Electron 默认禁用 Node.js 集成(nodeIntegration: false),所以直接在渲染进程里调用 fs.readFile 或 require('fs') 会报 ReferenceError: require is not defined。这不是 HTML5 本身的问题,而是 Electron 的安全策略切断了 DOM 与 Node.js 的默认通道。
实际能用的 HTML5 原生能力包括:fetch、localStorage、Canvas、Web Workers、IndexedDB,以及通过 触发的 FileReader —— 这些不依赖 Node.js,可直接运行。
- 想读本地文件?用
+FileReader,别硬写fs.readFileSync - 想访问应用目录下的资源(比如
app.asar里的配置)?必须走主进程桥接,不能靠fetch('./config.json')直接加载(路径解析会失败) - 开启
nodeIntegration: true是最简方案,但会削弱安全沙箱,不推荐用于生产环境
用 contextBridge + ipcRenderer 安全暴露桌面能力
Electron 12+ 强制推荐使用预加载脚本(preload.js)配合 contextBridge 向渲染进程注入受控 API。这是目前最稳妥的 HTML5 与桌面功能集成方式。
例如:让网页点击按钮后选择并读取一个 JSON 文件:
立即学习“前端免费学习笔记(深入)”;
// preload.js
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('api', {
openFile: () => ipcRenderer.invoke('dialog:openFile'),
readFile: (path) => ipcRenderer.invoke('fs:readFile', path)
})
然后在 HTML5 页面中直接调用:
- 所有 Node.js 操作(
dialog、fs、path)必须放在主进程处理,渲染进程只负责触发和接收结果 -
ipcRenderer.invoke是 Promise 风格,比send+on更适合 HTML5 中的异步流程 - 别在
contextBridge.exposeInMainWorld里暴露原始ipcRenderer或require,否则等于绕过安全限制
HTML5 的 drag & drop 在 Electron 中需手动启用
Electron 渲染进程默认拦截了原生拖拽事件(防止误拖出窗口),所以即使写了 ondragover 和 ondrop,也收不到文件列表。
必须在 webPreferences 中显式开启:
new BrowserWindow({
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
enableWebDragDrop: true // ← 关键开关
}
})
之后才能正常使用 HTML5 拖拽 API:
拖文件到这里
-
enableWebDragDrop: true不代表自动处理文件读取,仍需配合FileReader或 IPC 调用主进程 - 拖入的
File对象只有浏览器沙箱内路径(如C:\fakepath\config.json),真实路径需主进程确认或通过dialog.showOpenDialog获取 -
macOS 上拖拽到 Dock 图标再进窗口,可能触发两次
ondrop,注意去重
静态资源路径在打包后容易 404,HTML5 的 fetch 不能直接相对引用
开发时 fetch('./assets/icon.png') 没问题,但打包成 app.asar 后,路径变成只读归档,且 Electron 的 file:// 协议对相对路径解析规则和浏览器不同。
正确做法是用 app.getAppPath() 或 app.getPath('userData') 构建绝对路径,再通过 IPC 传给渲染进程,或使用 protocol.handle 注册自定义协议:
// main.js
app.whenReady().then(() => {
protocol.handle('app', (req) => {
const path = join(app.getAppPath(), 'assets', new URL(req.url).pathname)
return net.fetch(`file://${path}`)
})
})
// 渲染进程
fetch('app://./assets/icon.png') // ✅ 可用
- 别用
__dirname或process.cwd()拼接路径,它们在 asar 包里指向的是归档内部,不是解压后的实际位置 -
fetch无法跨协议请求(比如从file://请求http://),但 Electron 允许file://加载本地资源,前提是路径合法且未被 CORS 干扰 - 图片、字体等资源建议统一走
protocol.handle或构建时复制到resources/目录并用app.getPath('appData')动态定位










