Из-за чего не работает прокси в AxiOS на Electon JS (в файле preload.js)?

Ссылка скопирована
1 ответ

По вводным: создаю приложение на Electon JS, появилась задача использовать прокси в некоторых запросах.

По вводным: взял самый простой пример:

const axios = require("axios"); axios({ method: 'get', url: "https://api.ipify.org/?format=json", proxy: { protocol: "http", host: "11.11.111.111", port: "1111", auth: {username: "username", password: "password"} } }) .then(res => console.log("IP:" + res.data.ip)) .catch(err => console.error(err));

По вводным: этот код работает если поместить в файл js и напрямую запустить через Node.
По вводным: этот код работает если поместь в main.js, стартовый файл Electon JS.
По вводным: но как только я переношу его в preload.js, прокси перестаёт работать и выдаёт реальный IP адрес компьютера.

Сейчас ситуация такая: я уже наладить запросы в preload.js через iПКRenderer, но мне это не очень удобно, делает большую вложенность и вообще хочу понять можно ли это как то обойти и почему так происходит.

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Елена Вебер Ответ

В preload.js у Electron вы попадаете не в обычную Node-среду, а в изолированный мост между renderer и main. Даже если в preload доступен require, сетевой стек может вести себя иначе: часть запросов идет через Chromium/renderer, часть через Node, а настройки proxy у axios работают только для конкретного HTTP(S)-агента. Поэтому нормальная схема для прокси в Electron — держать реальные сетевые запросы в main process, а из preload только вызывать их через безопасный IPC.

Самый надежный вариант: в preload экспортировать метод, а в main.js выполнять axios-запрос с proxy или с httpAgent/httpsAgent. Тогда запрос выполняется в одном понятном окружении, без сюрпризов contextIsolation, sandbox и политики renderer.

/* preload.js */
const { contextBridge, ipcRenderer } = require('electron');
 
contextBridge.exposeInMainWorld('api', {
  getIpThroughProxy: () => ipcRenderer.invoke('proxy:get-ip')
});
 
/* main.js */
const { ipcMain } = require('electron');
const axios = require('axios');
 
ipcMain.handle('proxy:get-ip', async () => {
  const res = await axios.get('https://api.ipify.org/?format=json', {
    proxy: {
      protocol: 'http',
      host: '11.11.111.111',
      port: 1111,
      auth: {
        username: 'username',
        password: 'password'
      }
    },
    timeout: 15000
  });
 
  return res.data;
});

/* preload.js */ const { contextBridge, ipcRenderer } = require('electron'); contextBridge.exposeInMainWorld('api', { getIpThroughProxy: () => ipcRenderer.invoke('proxy:get-ip') }); /* main.js */ const { ipcMain } = require('electron'); const axios = require('axios'); ipcMain.handle('proxy:get-ip', async () => { const res = await axios.get('https://api.ipify.org/?format=json', { proxy: { protocol: 'http', host: '11.11.111.111', port: 1111, auth: { username: 'username', password: 'password' } }, timeout: 15000 }); return res.data; });

Если принципиально нужно выполнять запрос именно из renderer, лучше не рассчитывать на параметр proxy в axios, а настроить прокси на уровне сессии Electron. Например, для окна можно задать proxyRules через session.setProxy, а потом уже делать fetch/axios из renderer. Но это повлияет на сетевой трафик этой сессии, поэтому такой подход удобен, когда прокси нужен всему окну, а не одному запросу.

const { session } = require('electron');
 
await session.defaultSession.setProxy({
  proxyRules: 'http://username:password@11.11.111.111:1111'
});

const { session } = require('electron'); await session.defaultSession.setProxy({ proxyRules: 'http://username:password@11.11.111.111:1111' });

Я бы оставил запросы в main.js. Это проще отлаживать, безопаснее для логинов прокси и не заставляет тянуть секреты в preload/renderer. Проверьте также, не включен ли sandbox у BrowserWindow, какая версия Electron используется и не подменяется ли axios сборщиком. Для диагностики выведите process.type, process.versions.electron и сделайте контрольный запрос из main, preload и renderer отдельно.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно