Сеть и внешние коммуникации в Electron

Приложения Electron могут не только работать с локальными ресурсами, но и взаимодействовать с внешними сетевыми сервисами.
Будь то отправка HTTP-запросов, установка WebSocket-соединений в реальном времени или использование нативныхnetмодулей Node.js, вы можете выполнять сетевое взаимодействие так же, как в браузере или на сервере.


HTTP-запрос

Electron также поддерживаетбраузерный API (fetch)истороннюю библиотеку (axios)и может обрабатывать проблемы с кросс-доменными запросами и аутентификацией.


Использование fetch API

fetch— это встроенный в современные браузеры и Node.js (18+) интерфейс сетевых запросов.
Он поддерживает Promise, имеет понятный синтаксис и подходит для обычных запросов данных.

Пример

// Пример GET-запроса
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:

Пример

const socket = new WebSocket('wss://echo.websocket.org');

socket.onopen = () => {
  console.log('Соединение WebSocket установлено');
  socket.send('Привет, сервер!');
};

socket.onmessage = (event) => {
  console.log('Получено сообщение:', event.data);
};

socket.onclose = () => {
  console.log('Соединение закрыто');
};

Описание параметра:

  • new WebSocket(url): Создать соединение;
  • socket.send(data): Отправить сообщение;
  • onmessageСлушать ответ сервера;
  • oncloseСлушать закрытие соединения.

Пример приложения для связи в реальном времени

Предположим, мы создаём интерфейс чат-комнаты реального времени:

Пример

const socket = new WebSocket('wss://chat.example.com');

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 процесса рендеринга:

Пример

<input id="input" placeholder="Введите сообщение">
<button onclick="sendMessage()">Отправить</button>
<div id="messages"></div>

Этот шаблон позволяет легко реализовать чат в реальном времени, синхронизацию состояния, совместное редактирование и другие возможности.


Встроенный сетевой модуль

Главный процесс Electron предоставляет Node.jsnetмодули могут напрямую создавать соединения TCP или IPC на более низком уровне, что подходит для пользовательских протоколов или взаимодействия с локальными службами.

Использование модуля net

netМодуль позволяет создавать TCP-клиентов или серверы.

Создайте TCP-сервер:

Пример

const net = require('net');

const server = net.createServer(socket => {
  console.log('Клиент подключен');
  socket.write(Добро пожаловать в Electron TCP Server);
 
  socket.on('data', data => {
    console.log('Полученные данные:', data.toString());
  });
});

server.listen(8080, () => {
  console.log('TCP-сервер запущен, порт 8080');
});

Подключение TCP-клиента:

Пример

const client = net.createConnection({ port: 8080 }, () => {
  console.log('Подключено к серверу');
  client.write('Привет, сервер!');
});

client.on('data', data => {
  console.log('Ответ сервера:', data.toString());
});

Описание параметра:

  • net.createServer(callback): Создать сервер;
  • socket.write(data): Отправить данные;
  • socket.on('data'): Получить данные;
  • server.listen(port): Прослушивать порт.

управление сессиями

В ElectronsessionМодуль может управлять информацией о сетевых сессиях, такой как кэш, куки, прокси и многое другое.

Пример

const { session } = require('electron');

const ses = session.defaultSession;

// Очистить кеш
ses.clearCache().then(() => console.log('Кэш очищен'));

// Установить прокси
ses.setProxy({ proxyRules: 'http=127.0.0.1:8080' });

Обработка куки

Пример

const { session } = require('electron');
const cookies = session.defaultSession.c;

// Куки
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
Управление состоянием входа / кэшем сессия + cookies

Эта многоуровневая сетевая возможность позволяет приложениям Electron как получать доступ к облачным API, так и работать во взаимодействии с локальными службами.


Пример

Следующий пример — это краткая «панель данных в реальном времени», которая может отображать данные, получаемые из API в процессе рендеринга, принимать сообщения WebSocket в реальном времени и управлять cookies состояния входа.

I. Структура проекта

my-electron-network-demo/
├── package.json
├── main.js             # 主进程逻辑
├── preload.js          # 预加载脚本
└── index.html          # 前端界面

2. 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

3. main.js (главный процесс)

Пример

const { app, BrowserWindow, ipcMain, session } = require('electron')
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.c
  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.c
  const result = await cookies.get({ url: 'http://localhost', name })
  return result.length ? result[0].value : null
})

app.whenReady().then(() => {
  createWindow()
})

4. preload.js (Безопасное взаимодействие)

Пример

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

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)
})

5. index.html (Интерфейс процесса рендеринга)

Пример

<!DOCTYPE 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: ${value}</p>`
    })
  </script>
</body>
</html>

VI. Запуск и эффекты

npm start
  • НажмитеПолучить HTTP-данные: получите данные API через axios и отобразите их на странице.
  • НажмитеПодключить WebSocket: установите соединение в реальном времени и получайте сообщение каждые 3 секунды.
  • НажмитеУстановить cookie: создайтеtoken cookie.
  • НажмитеПрочитать cookie: прочитайте и отобразитеtokenзначение.
Другие расширения