Модернизация расширения для браузера Firefox - организация получения настроек(адресов прокси серверов) с удалённого сервера(в исходной версии настройки хранились в константе)

Гобелен - кликните для возврата на главную

Не прошло и месяца а Фурмановская ЦРБ в очередной раз попала в историю. На этот раз сотрудница клеветала на пациентов, а именно огласку получил случай когда сотрудница назвала пациента алкашём.

Так почему бы не начать использовать обход блокировки YouTube при том что техническая возможность используя расширение nikolaevevge для браузера Mozilla Firefox уже появилась, а объем полезной(и не очень) информации на видеохостинге YouTube, по мнению некоторых диванных экспертов, меньше не стал.

Ровно 3 года назад произошло событие, которое подарило жителям планеты Змеля новый чистый праздник 6 апреля - в этот замечательный день земля забрала гнить негодяя и СПАМера Владимира Вольфовича Жириновского.

Как бы не обстояли дела в области культуры и IT-технологий, Самосвал писал статьи на связанные темы и планирует ещё написать.

На очередном конкурсе танцев, школьница отлично выступила.

Что использовать вместо Юбуст

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

Начал разбираться с информацией которая находится в HTTPS клиентском запросе рукопожатия.

Обратите внимание! Объект изображённый на гобилене может отличаться от общепринятого вида описанного объекта. Тут дело в том что художник видит именно так!

104 549 руб.

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

Есть некоторое расширение для Firefox. Ниже я приведу его код. Его требуется доработать, а именно в файле background.js требуется чтобы 2 указанных в нём прокси сервера получались в результате запроса к 10-11/getProxDataBeta.php, запрос возвращает массив(в JSON, кстати именно массив а не объект) такого вида: ["ru" => ["ip" => "IP1", "port" => "НомерПорта1"], "en" => ["ip" => "IP2", "port" => "НомерПорта2"]](IP2 заменяет вот этот адрес 1.1.1.1, соответственно IP1 тот который в PROXY2) Вот файлы текущей версии расширения(разделитель между файлами несколько знаков =(равно)):

Файл backgroung.js

JSON
    
const PROXY = {
  host: "1.1.1.1",
  port: 1088
};
const PROXY2 = {
  host: "2.2.2.2",
  port: 1088
};
      
const DEFAULT_SETTINGS = {
  masterSwitch: true,
  googlevideo: true,
  youtube: true,
  ytimg: true,
  ggpht: true
};
      
let currentSettings = {...DEFAULT_SETTINGS};
let proxyListener = null;
      
async function getSettings() {
  const settings = await browser.storage.local.get(DEFAULT_SETTINGS);
  currentSettings = {...DEFAULT_SETTINGS, ...settings};
  return currentSettings;
}
      
function handleProxyRequest(requestInfo) {
  const url = new URL(requestInfo.url);
  const hostname = url.hostname;
      
  if (!currentSettings.masterSwitch) {
    return { type: "direct" };
  }
      
  // Первая группа сайтов (всегда через PROXY)
  if (hostname.endsWith('instagram.com') || 
      hostname.endsWith('fbcdn.net') || 
      hostname.endsWith('chatgpt.com') || 
      hostname.endsWith('fb.com') || 
      hostname.endsWith('facebook.com') || 
      hostname.endsWith('ionos.com')) {
    console.log(`Проксируем (PROXY1) запрос к: ${hostname}`);
    return {
      type: "socks",
      host: PROXY.host,
      port: PROXY.port,
      proxyDNS: true,
      failoverTimeout: 5
    };
  }
      
  // Вторая группа сайтов (зависит от настроек)
  if (hostname.endsWith('googlevideo.com') && currentSettings.googlevideo) {
    console.log(`Проксируем (PROXY2) запрос к: ${hostname}`);
    return {
      type: "socks",
      host: PROXY2.host,
      port: PROXY2.port,
      proxyDNS: true,
      failoverTimeout: 5
    };
  }
  if (hostname.endsWith('youtube.com') && currentSettings.youtube) {
    console.log(`Проксируем (PROXY2) запрос к: ${hostname}`);
    return {
      type: "socks",
      host: PROXY2.host,
      port: PROXY2.port,
      proxyDNS: true,
      failoverTimeout: 5
    };
  }
  if (hostname.endsWith('ytimg.com') && currentSettings.ytimg) {
    console.log(`Проксируем (PROXY2) запрос к: ${hostname}`);
    return {
      type: "socks",
      host: PROXY2.host,
      port: PROXY2.port,
      proxyDNS: true,
      failoverTimeout: 5
    };
  }
  if (hostname.endsWith('ggpht.com') && currentSettings.ggpht) {
    console.log(`Проксируем (PROXY2) запрос к: ${hostname}`);
    return {
      type: "socks",
      host: PROXY2.host,
      port: PROXY2.port,
      proxyDNS: true,
      failoverTimeout: 5
    };
  }
      
  return { type: "direct" };
}
      
async function setupProxy() {
  // Удаляем предыдущий слушатель, если он есть
  if (proxyListener) {
    browser.proxy.onRequest.removeListener(proxyListener);
  }
      
  // Получаем актуальные настройки
  await getSettings();
      
  // Создаем новый слушатель с актуальными настройками
  proxyListener = handleProxyRequest;
  browser.proxy.onRequest.addListener(
    proxyListener,
    { urls: ["*://*.googlevideo.com/*", "*://googlevideo.com/*", 
             "*://*.instagram.com/*", "*://instagram.com/*", 
             "*://*.fbcdn.net/*", "*://fbcdn.net/*", 
             "*://*.facebook.com/*", "*://facebook.com/*", 
             "*://*.fbcom/*", "*://fb.com/*",
             "*://*.youtube.com/*", "*://youtube.com/*", 
             "*://*.chatgpt.com/*", "*://chatgpt.com/*", 
             "*://*.ionos.com/*", "*://ionos.com/*", 
             "*://*.ytimg.com/*", "*://ytimg.com/*", 
             "*://*.ggpht.com/*", "*://ggpht.com/*"] }
  );
      
  console.log("Прокси обновлено с новыми настройками", currentSettings);
}
      
// Инициализация
browser.runtime.onStartup.addListener(() => {
  browser.storage.local.set(DEFAULT_SETTINGS);
  setupProxy();
});
      
browser.runtime.onInstalled.addListener(() => {
  browser.storage.local.set(DEFAULT_SETTINGS);
  setupProxy();
});
      
// Реагируем на изменения настроек
browser.storage.onChanged.addListener(async (changes, area) => {
  if (area === "local") {
    console.log("Обнаружены изменения настроек", changes);
    await setupProxy();
  }
});
      
setupProxy();

  

Файл manifest.json

JSON
    
{
  "manifest_version": 2,
  "name": "2ip.ru через SOCKS5",
  "version": "2.0",
  "description": "Корректное проксирование только 2ip.ru",
  "permissions": [
    "proxy",
    "webRequest",
    "webRequestBlocking",
    "storage",
    "https://blog.ivru.net/",
    "*://*.googlevideo.com/*",
    "*://googlevideo.com/*",
    "*://*.instagram.com/*",
    "*://instagram.com/*",
    "*://*.fbcdn.net/*",
    "*://fbcdn.net/*",
    "*://*.facebook.com/*",
    "*://facebook.com/*",
    "*://*.fbcom/*",
    "*://fb.com/*",
    "*://*.chatgpt.com/*",
    "*://chatgpt.com/*",
    "*://*.youtube.com/*",
    "*://youtube.com/*",
    "*://*.ionos.com/*",
    "*://ionos.com/*",
    "*://*.ytimg.com/*",
    "*://ytimg.com/*",
    "*://*.ggpht.com/*",
    "*://ggpht.com/*"
  ],
  "background": {
    "scripts": ["background.js"],
    "persistent": true
  },
  "browser_action": {
    "default_popup": "popup.html",
    "default_icon": {
      "48": "icon.png"
    }
  },
  "content_security_policy": "script-src 'self'; object-src 'self'; connect-src 'self' https://blog.ivru.net/",
  "web_accessible_resources": [
    "popup.html",
    "popup.js"
  ]
}

  
========================
HTML
    <!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <style>
    body {
      background-color: #000;
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 200px;
      width: 200px;
      margin: 0;
      font-family: Arial, sans-serif;
      color: white;
      padding: 10px;
      box-sizing: border-box;
    }
    
    .container {
      width: 100%;
    }
    
    .header {
      text-align: center;
      margin-bottom: 15px;
      font-weight: bold;
    }
    
    .switch-row {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 15px;
    }
    
    .switch-label {
      font-size: 14px;
    }
    
    .checkbox-container {
      width: 24px;
      height: 24px;
      border: 2px solid white;
      position: relative;
      box-sizing: border-box;
    }
    
    .switch-track {
      position: absolute;
      width: 4px;
      height: calc(100% - 8px);
      top: 4px;
      background-color: #ff0000;
      transition: all 0.2s ease;
    }
    
    .switch-track {
      left: 4px;
    }
    
    input:checked ~ .checkbox-container .switch-track {
      right: 4px;
      left: auto;
      background-color: #00ff00;
    }
    
    input[type="checkbox"] {
      display: none;
    }
    
    label {
      display: block;
      cursor: pointer;
    }
    
    .divider {
      height: 1px;
      background-color: #333;
      margin: 10px 0;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">Proxy Control</div>
    
    <div class="switch-row">
      <span class="switch-label">Master Switch</span>
      <label>
        <input type="checkbox" id="master-switch" checked>
        <div class="checkbox-container">
          <div class="switch-track"></div>
        </div>
      </label>
    </div>
    
    <div class="divider"></div>
    
    <div class="switch-row">
      <span class="switch-label">googlevideo.com</span>
      <label>
        <input type="checkbox" id="googlevideo-switch" checked>
        <div class="checkbox-container">
          <div class="switch-track"></div>
        </div>
      </label>
    </div>
    
    <div class="switch-row">
      <span class="switch-label">youtube.com</span>
      <label>
        <input type="checkbox" id="youtube-switch" checked>
        <div class="checkbox-container">
          <div class="switch-track"></div>
        </div>
      </label>
    </div>
    
    <div class="switch-row">
      <span class="switch-label">ytimg.com</span>
      <label>
        <input type="checkbox" id="ytimg-switch" checked>
        <div class="checkbox-container">
          <div class="switch-track"></div>
        </div>
      </label>
    </div>
    
    <div class="switch-row">
      <span class="switch-label">ggpht.com</span>
      <label>
        <input type="checkbox" id="ggpht-switch" checked>
        <div class="checkbox-container">
          <div class="switch-track"></div>
        </div>
      </label>
    </div>
  </div>
  
  <script src="popup.js"></script>
</body>
</html>

  
======================== async function loadSettings() { const result = await browser.storage.local.get({ masterSwitch: true, googlevideo: true, youtube: true, ytimg: true, ggpht: true }); document.getElementById('master-switch').checked = result.masterSwitch; document.getElementById('googlevideo-switch').checked = result.googlevideo; document.getElementById('youtube-switch').checked = result.youtube; document.getElementById('ytimg-switch').checked = result.ytimg; document.getElementById('ggpht-switch').checked = result.ggpht; } async function saveSettings() { const settings = { masterSwitch: document.getElementById('master-switch').checked, googlevideo: document.getElementById('googlevideo-switch').checked, youtube: document.getElementById('youtube-switch').checked, ytimg: document.getElementById('ytimg-switch').checked, ggpht: document.getElementById('ggpht-switch').checked }; await browser.storage.local.set(settings); console.log("Настройки сохранены", settings); } document.addEventListener('DOMContentLoaded', loadSettings); // Добавляем задержку 300мс перед сохранением, чтобы избежать частых обновлений const debouncedSave = debounce(saveSettings, 300); document.getElementById('master-switch').addEventListener('change', debouncedSave); document.getElementById('googlevideo-switch').addEventListener('change', debouncedSave); document.getElementById('youtube-switch').addEventListener('change', debouncedSave); document.getElementById('ytimg-switch').addEventListener('change', debouncedSave); document.getElementById('ggpht-switch').addEventListener('change', debouncedSave); // Функция для дебаунсинга function debounce(func, wait) { let timeout; return function() { const context = this, args = arguments; clearTimeout(timeout); timeout = setTimeout(() => { func.apply(context, args); }, wait); }; } Вот доработанный файл background.js, который получает прокси-серверы через запрос к 10-11/getProxDataBeta.php: javascript const DEFAULT_SETTINGS = { masterSwitch: true, googlevideo: true, youtube: true, ytimg: true, ggpht: true }; let currentSettings = {...DEFAULT_SETTINGS}; let proxyListener = null; let PROXY = null; let PROXY2 = null; async function fetchProxies() { try { const response = await fetch('https://10-11/getProxDataBeta.php'); const data = await response.json(); // Преобразуем полученные данные в нужный формат PROXY = { host: data.en.ip, port: data.en.port }; PROXY2 = { host: data.ru.ip, port: data.ru.port }; console.log('Прокси успешно получены:', { PROXY, PROXY2 }); } catch (error) { console.error('Ошибка при получении прокси:', error); // Используем значения по умолчанию в случае ошибки PROXY = { host: "1.1.1.1", port: 1088 }; PROXY2 = { host: "2.2.2.2", port: 1088 }; } } async function getSettings() { const settings = await browser.storage.local.get(DEFAULT_SETTINGS); currentSettings = {...DEFAULT_SETTINGS, ...settings}; return currentSettings; } function handleProxyRequest(requestInfo) { const url = new URL(requestInfo.url); const hostname = url.hostname; if (!currentSettings.masterSwitch || !PROXY || !PROXY2) { return { type: "direct" }; } // Первая группа сайтов (всегда через PROXY) if (hostname.endsWith('instagram.com') || hostname.endsWith('fbcdn.net') || hostname.endsWith('chatgpt.com') || hostname.endsWith('fb.com') || hostname.endsWith('facebook.com') || hostname.endsWith('ionos.com')) { console.log(`Проксируем (PROXY1) запрос к: ${hostname}`); return { type: "socks", host: PROXY.host, port: PROXY.port, proxyDNS: true, failoverTimeout: 5 }; } // Вторая группа сайтов (зависит от настроек) if (hostname.endsWith('googlevideo.com') && currentSettings.googlevideo) { console.log(`Проксируем (PROXY2) запрос к: ${hostname}`); return { type: "socks", host: PROXY2.host, port: PROXY2.port, proxyDNS: true, failoverTimeout: 5 }; } if (hostname.endsWith('youtube.com') && currentSettings.youtube) { console.log(`Проксируем (PROXY2) запрос к: ${hostname}`); return { type: "socks", host: PROXY2.host, port: PROXY2.port, proxyDNS: true, failoverTimeout: 5 }; } if (hostname.endsWith('ytimg.com') && currentSettings.ytimg) { console.log(`Проксируем (PROXY2) запрос к: ${hostname}`); return { type: "socks", host: PROXY2.host, port: PROXY2.port, proxyDNS: true, failoverTimeout: 5 }; } if (hostname.endsWith('ggpht.com') && currentSettings.ggpht) { console.log(`Проксируем (PROXY2) запрос к: ${hostname}`); return { type: "socks", host: PROXY2.host, port: PROXY2.port, proxyDNS: true, failoverTimeout: 5 }; } return { type: "direct" }; } async function setupProxy() { // Удаляем предыдущий слушатель, если он есть if (proxyListener) { browser.proxy.onRequest.removeListener(proxyListener); } // Получаем актуальные настройки и прокси await getSettings(); await fetchProxies(); // Создаем новый слушатель с актуальными настройками proxyListener = handleProxyRequest; browser.proxy.onRequest.addListener( proxyListener, { urls: ["*://*.googlevideo.com/*", "*://googlevideo.com/*", "*://*.instagram.com/*", "*://instagram.com/*", "*://*.fbcdn.net/*", "*://fbcdn.net/*", "*://*.facebook.com/*", "*://facebook.com/*", "*://*.fbcom/*", "*://fb.com/*", "*://*.youtube.com/*", "*://youtube.com/*", "*://*.chatgpt.com/*", "*://chatgpt.com/*", "*://*.ionos.com/*", "*://ionos.com/*", "*://*.ytimg.com/*", "*://ytimg.com/*", "*://*.ggpht.com/*", "*://ggpht.com/*"] } ); console.log("Прокси обновлено с новыми настройками", currentSettings); } // Инициализация browser.runtime.onStartup.addListener(() => { browser.storage.local.set(DEFAULT_SETTINGS); setupProxy(); }); browser.runtime.onInstalled.addListener(() => { browser.storage.local.set(DEFAULT_SETTINGS); setupProxy(); }); // Реагируем на изменения настроек browser.storage.onChanged.addListener(async (changes, area) => { if (area === "local") { console.log("Обнаружены изменения настроек", changes); await setupProxy(); } }); // Обновляем прокси каждые 5 минут setInterval(fetchProxies, 5 * 60 * 1000); // Первоначальная настройка setupProxy(); Основные изменения: Удалены константы PROXY и PROXY2, теперь они получаются динамически Добавлена функция fetchProxies() для получения прокси с сервера Добавлена периодическая проверка прокси (каждые 5 минут) Добавлена обработка ошибок при получении прокси (используются значения по умолчанию) Проверка наличия прокси перед их использованием Также вам нужно добавить домен 10-11 в разрешения в manifest.json:
JSON
    
"permissions": [
  ...
  "https://10-11/getProxDataBeta.php",
  ...
],
"content_security_policy": "script-src 'self'; object-src 'self'; connect-src 'self' https://blog.ivru.net/ https://10-11/"

  

Этот код корректно не заработал, так как расширение зависало в момент инициализации, исправление этой ситуации в статье по ссылке.

Другие товары

Вы так же можете прочитать следующие статьи: