Расширение Firefox

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

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

После того как в некоторых случаях перестала работать программа goodbydpi появились сложности с просмотром сайта YouTube. В конце мая 2025 года стало доступно расширение позволяющее разблокировать сайт YouTube в браузере Firefox на территории России.

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

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

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

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

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

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

104 549 руб.

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

Доброго времени суток. Вопрос про расширение для Firefox. Ситуация следующая, так как расширение которое я в частности сейчас делаю обменивается данными с сервером(расширения), мне необходимо как то отличать экземпляры которые присылают данные. Подскажите пожалуйста есть ли при установке приложения какой то идентификатор который не меняется про последующих загрузках браузера. И если ли сессионный идентификатор который меняется при перезагрузке браузера. Приведите пример расширения которое в окне(которое появляется при клике на расширение на панели) будет отображать первый и второй вариант идентификатора. Если системно таковых идентификаторов не существует, реализуйте методы их генерации и хранения.

Идентификаторы для Firefox расширения

Для вашего Firefox расширения, которое обменивается данными с сервером, я предлагаю следующие подходы для идентификации экземпляров:

1. Постоянный идентификатор (не меняется после перезагрузки)

Firefox предоставляет API browser.runtime.id, но это ID самого расширения, а не его экземпляра. Для уникального идентификатора экземпляра можно использовать storage.local с генерируемым UUID.

2. Сессионный идентификатор (меняется после перезагрузки)

Для сессионного ID можно генерировать новый UUID при каждом запуске браузера.

Пример реализации

Вот полный код расширения, которое отображает оба идентификатора:

Файл manifest.json

JSON
    
{
  "manifest_version": 2,
  "name": "Instance ID Viewer",
  "version": "1.0",
  "description": "Displays persistent and session instance IDs",
  "icons": {
    "48": "icon.png"
  },
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },
  "permissions": [
    "storage"
  ]
}

  

Файл popup.html

HTML
    
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>ID Viewer</title>
  <style>
    body {
      width: 200px;
      padding: 10px;
      font-family: Arial, sans-serif;
    }
    .id-container {
      margin-bottom: 10px;
    }
    .id-label {
      font-weight: bold;
      display: block;
      margin-bottom: 5px;
    }
    .id-value {
      font-family: monospace;
      font-size: 12px;
      word-break: break-all;
    }
  </style>
</head>
<body>
  <div class="id-container">
    <span class="id-label">Persistent ID:</span>
    <span id="persistent-id" class="id-value"></span>
  </div>
  <div class="id-container">
    <span class="id-label">Session ID:</span>
    <span id="session-id" class="id-value"></span>
  </div>
  <script src="popup.js"></script>
</body>
</html>

  

Файл popup.js

javaScript
    
// Генерация UUID
function generateUUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    const r = Math.random() * 16 | 0;
    const v = c === 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
}
      
// Инициализация идентификаторов
async function initIds() {
  // Получаем или создаем постоянный ID
  let { persistentId } = await browser.storage.local.get('persistentId');
  if (!persistentId) {
    persistentId = generateUUID();
    await browser.storage.local.set({ persistentId });
  }
      
  // Получаем или создаем сессионный ID
  let { sessionId } = await browser.storage.session.get('sessionId');
  if (!sessionId) {
    sessionId = generateUUID();
    await browser.storage.session.set({ sessionId });
  }
      
  // Отображаем ID
  document.getElementById('persistent-id').textContent = persistentId;
  document.getElementById('session-id').textContent = sessionId;
}
      
// Запускаем при загрузке
document.addEventListener('DOMContentLoaded', initIds);

  

Как это работает

Постоянный идентификатор:

  • генерируется при первом запуске расширения;
  • сохраняется в browser.storage.local;
  • сохраняется между сессиями браузера;
  • может быть сброшен только при удалении расширения или очистке хранилища.

Сессионный идентификатор:

Генерируется при каждом запуске браузера Сохраняется в browser.storage.session (доступно в Firefox) Сбрасывается при закрытии браузера Альтернативный подход Если browser.storage.session недоступен в вашей версии Firefox, можно использовать обычный browser.storage.local с флагом сессии: javascript // Альтернативная реализация сессионного ID async function getSessionId() { // Проверяем, есть ли сохраненный ID сессии let { sessionId, sessionActive } = await browser.storage.local.get(['sessionId', 'sessionActive']); // Если нет ID или сессия неактивна (браузер был перезапущен) if (!sessionId || !sessionActive) { sessionId = generateUUID(); await browser.storage.local.set({ sessionId, sessionActive: true }); } return sessionId; } // При загрузке расширения помечаем сессию как активную browser.runtime.onStartup.addListener(() => { browser.storage.local.set({ sessionActive: true }); }); // При выгрузке расширения помечаем сессию как неактивную browser.runtime.onSuspend.addListener(() => { browser.storage.local.set({ sessionActive: false }); }); Это расширение будет показывать два идентификатора в popup-окне, что позволит вам различать экземпляры как на сервере, так и в аналитике. Есть предположение что Вы меняете сессионный идентификатор при загрузке конкретной страницы. Я имел ввиду загрузку браузера а не страницы. Вы совершенно правы! Давайте переработаем решение, чтобы сессионный идентификатор менялся только при запуске браузера, а не при загрузке каждой страницы или открытии popup. Исправленная реализация Основные изменения: Сессионный ID будет генерироваться при старте браузера Используем background script для управления сессией Popup будет только отображать заранее сгенерированные ID Обновленный manifest.json: json { "manifest_version": 2, "name": "Instance ID Viewer", "version": "1.0", "description": "Displays persistent and session instance IDs", "icons": { "48": "icon.png" }, "browser_action": { "default_icon": "icon.png", "default_popup": "popup.html" }, "background": { "scripts": ["background.js"], "persistent": false }, "permissions": [ "storage" ] } Новый файл background.js:
JavaScript
    
// Генерация UUID
function generateUUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    const r = Math.random() * 16 | 0;
    const v = c === 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
}
      
// Инициализация идентификаторов при запуске браузера
browser.runtime.onStartup.addListener(async () => {
  // Постоянный ID (если нет - создаем)
  let { persistentId } = await browser.storage.local.get('persistentId');
  if (!persistentId) {
    persistentId = generateUUID();
    await browser.storage.local.set({ persistentId });
  }
  
  // Генерируем новый сессионный ID при старте браузера
  const sessionId = generateUUID();
  await browser.storage.local.set({ sessionId });
});
      
// Также инициализируем при установке расширения
browser.runtime.onInstalled.addListener(async () => {
  const persistentId = generateUUID();
  const sessionId = generateUUID();
  await browser.storage.local.set({ persistentId, sessionId });
});
Обновленный popup.js:
      
javascript
// Просто отображаем сохраненные ID
async function displayIds() {
  const { persistentId, sessionId } = await browser.storage.local.get(['persistentId', 'sessionId']);
  
  document.getElementById('persistent-id').textContent = persistentId || 'Not set';
  document.getElementById('session-id').textContent = sessionId || 'Not set';
}
      
document.addEventListener('DOMContentLoaded', displayIds);

  

Как это теперь работает

При запуске браузера:

Срабатывает onStartup в background script Генерируется новый сессионный ID Постоянный ID остается неизменным (или создается при первом запуске) При открытии popup: Скрипт просто получает сохраненные значения из storage Не генерирует новые ID При установке расширения: Создаются оба идентификатора Преимущества этого подхода Сессионный ID меняется только при перезапуске браузера Нет лишних генераций ID при каждом открытии popup Background script работает только когда нужно (thanks to non-persistent) Все данные хранятся в storage.local, что гарантирует сохранность Альтернатива с sessionStorage Если вы хотите использовать sessionStorage (который очищается при закрытии браузера), можно модифицировать background script: javascript // В background.js browser.runtime.onStartup.addListener(async () => { const sessionId = generateUUID(); await browser.storage.session.set({ sessionId }); }); // В popup.js async function displayIds() { const persistentId = (await browser.storage.local.get('persistentId')).persistentId; const sessionId = (await browser.storage.session.get('sessionId')).sessionId; // ... отображение } Однако browser.storage.session доступен не во всех версиях Firefox, поэтому первый вариант более универсален. Смотрите какая ситуация. Сейчас действительно один идентификатор создаётся 1 раз и существует далее не зависимо от рестартов браузера и выключения плагина. Второй обновляется при перезагрузке браузера, при этом если выключить расширение затем перезапустить браузер и снова включить расширение, то второй идентификатор не изменится. Если не существует возможности каким то образом проверять был ли перезагружен браузер в время когда плагин был выключен(например может быть есть возможность получать время старта браузера и сравнивать его), то предлагаю добавить обновление второго идентификатора так же на запуск расширения. Вы подняли важный момент. Давайте реализуем гибридный подход, который будет учитывать оба сценария: Первый идентификатор - постоянный (как и раньше) Второй идентификатор - обновляется: При старте браузера (если расширение активно) При включении расширения (если браузер был перезапущен) Для этого добавим проверку времени последнего запуска браузера. Обновленная реализация manifest.json (добавляем разрешение на runtime): json { "manifest_version": 2, "name": "Instance ID Viewer", "version": "1.0", "description": "Displays persistent and session instance IDs", "icons": { "48": "icon.png" }, "browser_action": { "default_icon": "icon.png", "default_popup": "popup.html" }, "background": { "scripts": ["background.js"], "persistent": false }, "permissions": [ "storage", "runtime" ] } background.js: javascript function generateUUID() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { const r = Math.random() * 16 | 0; const v = c === 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } // Проверяем, был ли браузер перезапущен с момента последнего запуска расширения async function wasBrowserRestarted() { const { lastBrowserStartTime } = await browser.storage.local.get('lastBrowserStartTime'); const currentStartTime = await browser.runtime.getBrowserInfo().then(info => info.startTime); if (!lastBrowserStartTime || lastBrowserStartTime !== currentStartTime) { await browser.storage.local.set({ lastBrowserStartTime: currentStartTime }); return true; } return false; } // Основная логика инициализации async function initializeIds() { // Постоянный ID let { persistentId } = await browser.storage.local.get('persistentId'); if (!persistentId) { persistentId = generateUUID(); await browser.storage.local.set({ persistentId }); } // Проверяем рестарт браузера const browserRestarted = await wasBrowserRestarted(); // Сессионный ID - обновляем если: // 1. Браузер только что запущен // 2. Или это первая инициализация let { sessionId } = await browser.storage.local.get('sessionId'); if (!sessionId || browserRestarted) { sessionId = generateUUID(); await browser.storage.local.set({ sessionId }); } } // Обработчики событий browser.runtime.onStartup.addListener(initializeIds); browser.runtime.onInstalled.addListener(initializeIds); // Также вызываем при каждом включении расширения initializeIds(); popup.js (остается без изменений): javascript async function displayIds() { const { persistentId, sessionId } = await browser.storage.local.get(['persistentId', 'sessionId']); document.getElementById('persistent-id').textContent = persistentId || 'Not set'; document.getElementById('session-id').textContent = sessionId || 'Not set'; } document.addEventListener('DOMContentLoaded', displayIds); Как это теперь работает При старте браузера: onStartup вызывает инициализацию Фиксируется время старта браузера Генерируется новый сессионный ID При включении расширения: Проверяется время последнего старта браузера Если браузер был перезапущен - генерируется новый сессионный ID Если нет - используется существующий При установке: Создаются оба идентификатора Особенности реализации Используем browser.runtime.getBrowserInfo() для получения времени старта браузера Храним время последнего известного старта в storage.local При каждом вызове initializeIds() проверяем, изменилось ли время старта Сессионный ID обновляется в двух случаях: При первом запуске Если обнаружен рестарт браузера Это решение гарантирует, что сессионный ID будет обновляться: При перезапуске браузера (даже если расширение было выключено) При первом включении расширения после установки При ручном вызове инициализации

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

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