Гобелен - кликните для возврата на главную
Не прошло и месяца а Фурмановская ЦРБ в очередной раз попала в историю. На этот раз сотрудница клеветала на пациентов, а именно огласку получил случай когда сотрудница назвала пациента алкашём.
Так почему бы не начать использовать обход блокировки YouTube при том что техническая возможность используя расширение nikolaevevge для браузера Mozilla Firefox уже появилась, а объем полезной(и не очень) информации на видеохостинге YouTube, по мнению некоторых диванных экспертов, меньше не стал.
Ровно 3 года назад произошло событие, которое подарило жителям планеты Змеля новый чистый праздник 6 апреля - в этот замечательный день земля забрала гнить негодяя и СПАМера Владимира Вольфовича Жириновского.
Как бы не обстояли дела в области культуры и IT-технологий, Самосвал писал статьи на связанные темы и планирует ещё написать.
На очередном конкурсе танцев, школьница отлично выступила.
Вот та самая информация: программа для продвижения канала YouTube, эта информация выложена уже несколько лет, при этом просмотров не много, а метод который описан в данном видео действительно помогает продвигать видео в YouTube.
Начал разбираться с информацией которая находится в HTTPS клиентском запросе рукопожатия.
Обратите внимание! Объект изображённый на гобилене может отличаться от общепринятого вида описанного объекта. Тут дело в том что художник видит именно так!
Доброго времени суток. Вопрос про расширение для Firefox. Ситуация следующая, так как расширение которое я в частности сейчас делаю обменивается данными с сервером(расширения), мне необходимо как то отличать экземпляры которые присылают данные. Подскажите пожалуйста есть ли при установке приложения какой то идентификатор который не меняется про последующих загрузках браузера. И если ли сессионный идентификатор который меняется при перезагрузке браузера. Приведите пример расширения которое в окне(которое появляется при клике на расширение на панели) будет отображать первый и второй вариант идентификатора. Если системно таковых идентификаторов не существует, реализуйте методы их генерации и хранения.
Для вашего Firefox расширения, которое обменивается данными с сервером, я предлагаю следующие подходы для идентификации экземпляров:
1. Постоянный идентификатор (не меняется после перезагрузки)
Firefox предоставляет API browser.runtime.id, но это ID самого расширения, а не его экземпляра. Для уникального идентификатора экземпляра можно использовать storage.local с генерируемым UUID.
2. Сессионный идентификатор (меняется после перезагрузки)
Для сессионного ID можно генерировать новый UUID при каждом запуске браузера.
Пример реализации
Вот полный код расширения, которое отображает оба идентификатора:
Файл manifest.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
<!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
// Генерация 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.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:
// Генерация 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 будет обновляться: При перезапуске браузера (даже если расширение было выключено) При первом включении расширения после установки При ручном вызове инициализацииВы так же можете прочитать следующие статьи: