Electron ネットワークと外部通信

Electron アプリはローカルリソースを操作できるだけでなく、外部のネットワークサービスとやり取りすることもできます。
HTTP リクエストの発行、リアルタイム WebSocket 接続の確立、Node.js のネイティブnetモジュールの使用など、ブラウザやサーバー上と同様にネットワーク通信を行うことができます。


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('Hello Server!');
};

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.js のnetモジュールを提供し、より低レベルで TCP または IPC 接続を直接作成できます。カスタムプロトコルやローカルサービスのやり取りに適しています。

net モジュールの使用

netモジュールを使用すると、TCP クライアントまたはサーバーを作成できます。

TCP サーバーの作成:

例

const net = require('net');

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 クライアント接続:

例

const client = net.createConnection({ port: 8080 }, () => {
  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 { session } = require('electron');

const ses = session.defaultSession;

// キャッシュをクリア
ses.clearCache().then(() => console.log('キャッシュがクリアされました'));

// プロキシを設定
ses.setProxy({ proxyRules: 'http=127.0.0.1:8080' });

Cookie 処理

例

const { session } = require('electron');
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 { 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.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(安全な通信)

例

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

五、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>

六、実行と効果

npm start
  • クリックHTTP データを取得:axios を使用して API データを取得し、ページに表示します。
  • クリックWebSocket に接続:リアルタイム接続を確立し、3秒ごとにメッセージを受信します。
  • クリックCookie を設定:作成token Cookie。
  • クリックCookie を読み取り:読み取って表示token値。
その他の拡張