Пишем простое расширение для браузера
- воскресенье, 9 марта 2025 г. в 00:00:05
Всем привет! В этом туториале я хотел бы описать создание расширения для браузера на основе Chromium (Google Chrome, Brave, Яндекс Браузер и др.).
Расширения для браузеров создаются с использованием веб-технологий: HTML, CSS и JavaScript/TypeScript. Можно также применять библиотеки, такие как React или jQuery, а также фреймворки, например Vue. Однако можно обойтись и чистым JavaScript (Vanilla JS).
Наше расширение будет управлять куками на сайте. Реализуем следующий функционал:
Отображение кук
Удаление кук
Блокировка кук по домену
Разблокировка
Фильтрация
🚀 Давайте приступим! Весь код хранится в этом репозитории, и вы можете склонировать его себе, но советую сначала сделать всё самим.
Сама структура проекта простая:
manifest.json – конфигурационный файл расширения.
background.js – фоновый скрипт, управляющий логикой.
content scripts – скрипты, взаимодействующие с веб-страницами, в нашем случае - это popup.js
.
popup.html – сам интерфейс расширения.
Перед началом разработки убедитесь, что у вас установлен редактор кода и браузер (ну а вдруг нет). Создайте папку для проекта и внутри неё настройте следующую структуру файлов:
Иконки можно будет скачать здесь.
Начнем с первого файла - манифест – это основной файл конфигурации расширения. Создадим manifest.json
:
{
"manifest_version": 3,
"name": "Cookie Manager",
"version": "1.1",
"description": "Manage cookies: view, block, or delete cookies for specific websites.",
"permissions": ["cookies", "storage", "activeTab", "scripting", "webRequest", "webRequestBlocking"],
"host_permissions": ["<all_urls>"],
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
}
}
Стоит обратить внимание на некоторые поля конфигурации:
permissions – список разрешений, необходимых для работы расширения (например, доступ к cookies, хранилищу и активным вкладкам).
host_permissions – разрешенные домены, с которыми может взаимодействовать расширение.
background – указывает фоновый скрипт, который выполняется в сервис-воркере (background.js).
action – определяет настройки кнопки расширения в панели инструментов браузера (указываем popup и иконку).
Если в конфигурации будут ошибки, браузер не запустит расширение.
Пользовательский интерфейс будет в файле popup.html
. Добавим две кнопки: «Просмотреть куки» - при нажатии на неё будем получать все сохранённые в браузере куки, и «Удалить куки» - для их удаления.
Список куков будет динамически формироваться с помощью JavaScript в файле popup.js
. Позже мы его рассмотрим.
Также добавим поле ввода для блокировки домена, а ниже отобразим список заблокированных доменов.
Код popup.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Менеджер кук</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="wrapper">
<h2>Менеджер кук</h2>
<button id="viewCookies">Просмотреть куки</button>
<button id="deleteCookies">Удалить куки</button>
<h3>Блокировка домена</h3>
<input type="text" id="blockDomainInput" placeholder="Введите домен" />
<button id="blockDomain">Блокировать</button>
<ul id="blockList"></ul>
</div>
<script src="popup.js"></script>
</body>
</html>
Логика нашего расширения будет хранится в двух скриптах:
background.js
- фоновый скрипт выполняет задачи, которые работают независимо от пользовательского интерфейса, такие как обработка событий, работа с API браузера и управление данными. В нашем случае мы будем его использовать для блокировки домена.
popup.js
- содержится основная логика расширения. Здесь у нас обработчики кнопок и работа с куками.
Чтобы взаимодействовать с браузером нам нужен API. На помощь нам приходим объект chrome
, рассмотрим его основные методы:
chrome.runtime
– управление жизненным циклом расширения.
chrome.runtime.onMessage.addListener(callback)
– слушает сообщения между скриптами.
chrome.runtime.sendMessage(message, callback)
– отправляет сообщение другому скрипту.
chrome.tabs
– работа с вкладками.
chrome.tabs.query(queryInfo, callback)
– получает список вкладок.
chrome.tabs.create(properties, callback)
– открывает новую вкладку.
chrome.cookies
– управление cookies.
chrome.cookies.get(details, callback)
– получает информацию о cookie.
chrome.cookies.getAll(details, callback)
– получает все cookies.
chrome.cookies.remove(details, callback
) – удаляет cookie.
chrome.storage
– локальное хранилище данных.
chrome.storage.local.set(object, callback)
– сохраняет данные.
chrome.storage.local.get(keys, callback)
– получает сохраненные данные.
chrome.storage.sync.set(object, callback)
– сохраняет данные в облаке и синхронизирует их между устройствами пользователя.
chrome.storage.sync.get(keys, callback)
– получает синхронизированные данные.
chrome.notifications
– создание уведомлений.
chrome.notifications.create(options, callback)
– создает уведомление.
В background.js
добавим обработчик для перехвата заголовков запроса и блокировки доменов. Также выведем в консоль сообщение о том, что расширение установлено.
chrome.webRequest.onBeforeSendHeaders.addListener(
function (details) {
return new Promise((resolve) => {
chrome.storage.sync.get({ blockedDomains: [] }, (data) => {
let url = new URL(details.url);
if (data.blockedDomains.includes(url.hostname)) {
resolve({ cancel: true }); // Блокируем запрос, если домен в списке
} else {
resolve({ cancel: false });
}
});
});
},
{ urls: ["<all_urls>"] },
["blocking"]
);
chrome.runtime.onInstalled.addListener(() => {
console.log("Cookie Manager Extension Installed.");
});
Больше для этого файла нам нечего добалять.
Вся магия у нас будет описана в файле popup.js
. Здесь нам нужно добавить обработчики для кнопок, поля ввода и для работы с cookies.
Рассмотрим первый обработчик, который получает и отображает все cookies для текущей активной вкладки:
document.getElementById("viewCookies").addEventListener("click", () => {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
let url = tabs[0].url;
chrome.cookies.getAll({ url }, (cookies) => {
let cookieList = document.getElementById("blockList");
cookieList.innerHTML = "";
cookies.forEach(cookie => {
let li = document.createElement("li");
li.textContent = `${cookie.name} = ${cookie.value}`;
cookieList.appendChild(li);
});
});
});
});
Следующий фрагмент кода удаляет все cookies текущего сайта и уведомляет пользователя:
document.getElementById("deleteCookies").addEventListener("click", () => {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
let url = tabs[0].url;
chrome.cookies.getAll({ url }, (cookies) => {
cookies.forEach(cookie => {
chrome.cookies.remove({ url, name: cookie.name });
});
alert("Cookies deleted!");
});
});
});
Обработчик для добавления домена в список заблокированных и сохранение его в хранилище:
document.getElementById("blockDomain").addEventListener("click", () => {
let domain = document.getElementById("blockDomainInput").value.trim();
if (domain) {
chrome.storage.sync.get({ blockedDomains: [] }, (data) => {
let blockedDomains = new Set(data.blockedDomains);
blockedDomains.add(domain);
chrome.storage.sync.set({ blockedDomains: Array.from(blockedDomains) }, () => {
loadBlockedDomains();
alert(`Заблокирован ${domain}`);
});
});
}
});
Отображение заблокированных доменов, когда наше расширение стартовало:
document.addEventListener("DOMContentLoaded", () => {
loadBlockedDomains();
});
function loadBlockedDomains() {
chrome.storage.sync.get({ blockedDomains: [] }, (data) => {
let blockList = document.getElementById("blockList");
blockList.innerHTML = "";
data.blockedDomains.forEach(domain => {
let li = document.createElement("li");
li.textContent = domain;
let removeBtn = document.createElement("button");
removeBtn.textContent = "Разблокировать";
removeBtn.onclick = () => unblockDomain(domain);
li.appendChild(removeBtn);
blockList.appendChild(li);
});
});
}
Последний обработчик удаляет домен из списка заблокированных и обновляет интерфейс:
function unblockDomain(domain) {
chrome.storage.sync.get({ blockedDomains: [] }, (data) => {
let blockedDomains = data.blockedDomains.filter(d => d !== domain);
chrome.storage.sync.set({ blockedDomains }, () => {
loadBlockedDomains();
alert(`Разблокирован ${domain}`);
});
});
}
На этом все, ничего билдить не нужно, для тестирования работы нашего приложения переходим в браузер.
Чтобы запустить наше расширение нам нужно выполнить следующие шаги
1) Открываем chrome://extensions/
.
2) Включаем Режим разработчика.
3) Нажимаем Загрузить распакованное расширение и выбираем папку с проектом.
После того как вы выполните все шаги у вас в списке появится ваше расширение. Теперь мы можем его использовать на сайтах.
Также мы можем вызвать DevTools у расширения для отладки, то есть это по сути та же страница.
Этот шаг необязательный. Во-первых, возможно, вы не хотите делать доступным для всех свое расширение. А во-вторых, возможно, не захотите платить за это $5 - да, да за регистрацию нужно заплатить. Но я опишу шаги:
Регистрируемся в Chrome Web Store.
Зарегистрируйтесь как разработчик Chrome Web Store. Для этого войдите в консоль разработчика под своим аккаунтом Chrome.
Оплачиваем 5 баксов
В личном кабинет разработчика нажмите Добавить продукт и загрузите zip-архив проекта.
Заполняем описание и предоставляем скриншоты.
Проходим проверку и публикуем расширение.
Все.
Думаю тут вы справитесь без проблем!
На этом всё, наше расширение готово. Конечно можно еще добавить еще кучу функционала, но это я оставлю вам. Весь исходный код вы можете найти здесь.
📣 Подписывайтесь на мой телеграм канал Рассказ фронтендера.