Electron 网络与外部通信
Electron 应用不仅可以操作本地资源,也可以与外部网络服务进行交互。
无论是发起 HTTP 请求、建立实时 WebSocket 连接,还是使用 Node.js 的原生 net 模块,你都可以像在浏览器或服务器上一样进行网络通信。
HTTP 请求
Electron 同时支持 浏览器 API(fetch) 和 第三方库(axios),并且可以处理跨域与认证问题。
fetch API 使用
fetch 是现代浏览器与 Node.js(18+)内置的网络请求接口。
它支持 Promise,语法简洁,适合常规数据请求。
实例
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => {
if (!response.ok) throw new Error('网络响应错误');
return response.json();
})
.then(data => {
console.log('返回数据:', data);
})
.catch(error => {
console.error('请求失败:', error);
});
参数说明:
fetch(url, options):发起请求;options.method:请求方式(GET、POST、PUT、DELETE);options.headers:设置请求头;options.body:请求体,POST 时常用。
POST 示例:
fetch('https://api.example.com/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'admin', password: '123456' })
});
axios 集成
axios 是一个功能强大的 HTTP 客户端,支持拦截器、超时、并发等特性,常用于 Electron 应用中与后端 API 通信。
安装:
npm install axios
使用示例:
const axios = require('axios');
// GET 请求
axios.get('https://jsonplaceholder.typicode.com/users')
.then(res => console.log(res.data))
.catch(err => console.error(err));
// POST 请求
axios.post('https://api.example.com/data', { name: 'Tom' })
.then(res => console.log('上传成功', res.data))
.catch(err => console.error('上传失败', err));
参数说明:
axios.get(url, config):发起 GET 请求;axios.post(url, data, config):发起 POST 请求;config.timeout:设置超时时间;config.headers:自定义请求头。
处理跨域问题
在 Electron 中,因为运行在桌面环境,默认不存在浏览器的 CORS 限制。
但如果前端页面通过 BrowserWindow 加载网页内容并发请求,仍可能触发跨域问题。
解决方案:
使用 nodeIntegration:
在主进程中发起请求而不是渲染进程。
const { ipcMain } = require('electron');
const axios = require('axios');
ipcMain.handle('getData', async () => {
const res = await axios.get('https://api.example.com/data');
return res.data;
});
通过 session.webRequest 修改请求头:
const { session } = require('electron');
session.defaultSession.webRequest.onBeforeSendHeaders((details, callback) => {
details.requestHeaders['Origin'] = '*';
callback({ requestHeaders: details.requestHeaders });
});
WebSocket 通信
WebSocket 提供持久化、全双工的实时通信通道,非常适合用于聊天、数据推送、股票行情等应用。
WebSocket 客户端实现
Electron 可以直接使用浏览器原生的 WebSocket API:
实例
socket.onopen = () => {
console.log('WebSocket 连接已建立');
socket.send('Hello Server!');
};
socket.onmessage = (event) => {
console.log('收到消息:', event.data);
};
socket.onclose = () => {
console.log('连接已关闭');
};
参数说明:
new WebSocket(url):创建连接;socket.send(data):发送消息;onmessage:监听服务器返回;onclose:监听连接关闭。
实时通信应用示例
假设我们构建一个实时聊天室界面:
实例
socket.onmessage = (e) => {
const messageBox = document.getElementById('messages');
messageBox.innerHTML += `<div>${e.data}</div>`;
};
function sendMessage() {
const input = document.getElementById('input');
socket.send(input.value);
input.value = '';
}
渲染进程的 HTML:
实例
<button onclick="sendMessage()">发送</button>
<div id="messages"></div>
这种模式可以轻松实现实时聊天、状态同步、协同编辑等功能。
原生网络模块
Electron 的主进程提供了 Node.js 的 net 模块,可以在更底层直接创建 TCP 或 IPC 连接,适用于定制化协议或本地服务交互。
net 模块使用
net 模块允许你创建 TCP 客户端或服务器。
创建 TCP 服务器:
实例
const server = net.createServer(socket => {
console.log('客户端已连接');
socket.write('欢迎来到 Electron TCP 服务器');
socket.on('data', data => {
console.log('收到数据:', data.toString());
});
});
server.listen(8080, () => {
console.log('TCP 服务器已启动,端口 8080');
});
TCP 客户端连接:
实例
console.log('已连接到服务器');
client.write('Hello Server!');
});
client.on('data', data => {
console.log('服务器响应:', data.toString());
});
参数说明:
net.createServer(callback):创建服务器;socket.write(data):发送数据;socket.on('data'):接收数据;server.listen(port):监听端口。
session 管理
Electron 中的 session 模块可控制缓存、Cookie、代理等网络会话信息。
实例
const ses = session.defaultSession;
// 清除缓存
ses.clearCache().then(() => console.log('缓存已清除'));
// 设置代理
ses.setProxy({ proxyRules: 'http=127.0.0.1:8080' });
Cookie 处理
实例
const cookies = session.defaultSession.cookies;
// 设置 Cookie
cookies.set({
url: 'https://example.com',
name: 'token',
value: 'abc123',
expirationDate: Date.now() / 1000 + 3600
});
// 获取 Cookie
cookies.get({ url: 'https://example.com' })
.then(cookies => {
console.log('当前 Cookie:', cookies);
});
小结
在 Electron 中进行网络与外部通信时,可以灵活选择:
| 场景 | 推荐方案 |
|---|---|
| 普通 HTTP 请求 | fetch 或 axios |
| 实时数据 | WebSocket |
| 本地或底层通信 | net 模块 |
| 管理登录状态 / 缓存 | session + cookies |
这种多层级的网络能力,让 Electron 应用既能访问云端 API,也能与本地服务协同运行。
实例
以下实例是一个简洁的"实时数据仪表盘",可以在渲染进程显示从 API 获取的数据,并实时接收 WebSocket 消息,同时管理登录状态 Cookie。
一、项目结构
my-electron-network-demo/ ├── package.json ├── main.js # 主进程逻辑 ├── preload.js # 预加载脚本 └── index.html # 前端界面
二、package.json
{
"name": "my-electron-network-demo",
"version": "1.0.0",
"description": "Electron 网络通信综合示例",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"devDependencies": {
"electron": "latest",
"axios": "^1.5.0"
}
}
安装依赖:
npm install
三、main.js(主进程)
实例
const path = require('path')
const axios = require('axios')
const WebSocket = require('ws')
let mainWindow
function createWindow() {
mainWindow = new BrowserWindow({
width: 900,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
mainWindow.loadFile('index.html')
}
// HTTP 请求示例
ipcMain.handle('fetch-data', async () => {
try {
const res = await axios.get('https://jsonplaceholder.typicode.com/posts/1')
return res.data
} catch (err) {
return { error: err.message }
}
})
// WebSocket 服务器示例
const wss = new WebSocket.Server({ port: 8081 })
wss.on('connection', ws => {
console.log('客户端已连接 WebSocket')
ws.send('欢迎连接 WebSocket 实时数据')
// 定时推送数据
const interval = setInterval(() => {
ws.send(`实时消息:${new Date().toLocaleTimeString()}`)
}, 3000)
ws.on('close', () => clearInterval(interval))
})
// WebSocket 消息转发给渲染进程
ipcMain.handle('connect-ws', async () => {
return new Promise(resolve => {
const ws = new WebSocket('ws://localhost:8081')
ws.on('open', () => console.log('已连接到 WebSocket 服务器'))
ws.on('message', msg => {
mainWindow.webContents.send('ws-message', msg.toString())
})
resolve('WebSocket 连接已建立')
})
})
// Cookie 管理示例
ipcMain.handle('set-cookie', async (event, name, value) => {
const cookies = session.defaultSession.cookies
await cookies.set({
url: 'http://localhost',
name,
value,
expirationDate: Date.now() / 1000 + 3600
})
return 'Cookie 设置成功'
})
ipcMain.handle('get-cookie', async (event, name) => {
const cookies = session.defaultSession.cookies
const result = await cookies.get({ url: 'http://localhost', name })
return result.length ? result[0].value : null
})
app.whenReady().then(() => {
createWindow()
})
四、preload.js(安全通信)
实例
contextBridge.exposeInMainWorld('electronAPI', {
fetchData: () => ipcRenderer.invoke('fetch-data'),
connectWS: () => ipcRenderer.invoke('connect-ws'),
onWSMessage: (callback) => ipcRenderer.on('ws-message', (event, msg) => callback(msg)),
setCookie: (name, value) => ipcRenderer.invoke('set-cookie', name, value),
getCookie: (name) => ipcRenderer.invoke('get-cookie', name)
})
五、index.html(渲染进程界面)
实例
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Electron 网络通信示例</title>
<style>
body { font-family: sans-serif; padding: 20px; }
button { margin: 5px; padding: 10px 20px; cursor: pointer; }
#output { margin-top: 20px; }
</style>
</head>
<body>
<h1>Electron 网络通信示例</h1>
<button id="fetchBtn">获取 HTTP 数据</button>
<button id="wsBtn">连接 WebSocket</button>
<button id="setCookieBtn">设置 Cookie</button>
<button id="getCookieBtn">读取 Cookie</button>
<div id="output"></div>
<script>
const output = document.getElementById('output')
document.getElementById('fetchBtn').addEventListener('click', async () => {
const data = await window.electronAPI.fetchData()
output.innerHTML += `<p>HTTP 返回数据:${JSON.stringify(data)}</p>`
})
document.getElementById('wsBtn').addEventListener('click', async () => {
await window.electronAPI.connectWS()
output.innerHTML += `<p>WebSocket 连接已建立</p>`
})
window.electronAPI.onWSMessage(msg => {
output.innerHTML += `<p>WebSocket 消息:${msg}</p>`
})
document.getElementById('setCookieBtn').addEventListener('click', async () => {
const res = await window.electronAPI.setCookie('token', 'abc123')
output.innerHTML += `<p>${res}</p>`
})
document.getElementById('getCookieBtn').addEventListener('click', async () => {
const value = await window.electronAPI.getCookie('token')
output.innerHTML += `<p>Cookie token 值:${value}</p>`
})
</script>
</body>
</html>
六、运行与效果
npm start
- 点击 获取 HTTP 数据:通过 axios 获取 API 数据并显示在页面上。
- 点击 连接 WebSocket:建立实时连接,每 3 秒接收一条消息。
- 点击 设置 Cookie:创建
tokenCookie。 - 点击 读取 Cookie:读取并显示
token值。
点我分享笔记