Технічна реалізація перехоплення HTTP-запитів у браузерному розширенні
Клієнт ставить задачу: блокувати скрипти телеметрії, додавати авторизаційні заголовки до внутрішніх API та перенаправляти всі медіа-запити на швидкий CDN. Без перехоплення HTTP-запитів не обійтися. Ми реалізували десятки таких розширень і знаємо всі підводні камені — від обмежень Manifest V3 до нюансів крос-браузерної сумісності.
Наша команда має 7+ років досвіду у розробці браузерних розширень і виконала понад 50 проєктів.
Раніше розробники активно використовували chrome.webRequest з прапорцем blocking, але з переходом на Manifest V3 цей метод втратив гнучкість. Сучасний стандарт — declarativeNetRequest, декларативний API, який переносить обробку правил на рівень браузера. Він швидший, безпечніший і не навантажує основний потік, але накладає суворі ліміти: одночасно можна активувати не більше 5 000 правил. Розберемо, як проєктувати систему правил, щоб обійти обмеження та зберегти повний контроль над трафіком.
Перехоплення та модифікація HTTP-запитів у MV3
Як перехопити HTTP-запит у MV3?
В основу покладений декларативний підхід: ви описуєте правила в JSON, а браузер сам їх застосовує. Розширення не витрачає CPU на аналіз кожного запиту, а отже, Core Web Vitals не страждають.
Статичні правила
Правила, визначені у файлі rules/static.json, діють постійно. Приклад налаштування блоку аналітики, модифікації заголовків і редиректу:
[
{
"id": 1,
"priority": 1,
"action": { "type": "block" },
"condition": {
"urlFilter": "||analytics.example.com^",
"resourceTypes": ["script", "xmlhttprequest", "image"]
}
},
{
"id": 2,
"priority": 2,
"action": {
"type": "modifyHeaders",
"requestHeaders": [
{ "header": "X-Custom-Token", "operation": "set", "value": "my-token" },
{ "header": "Referer", "operation": "remove" }
]
},
"condition": {
"urlFilter": "https://api.internal.corp/*",
"resourceTypes": ["xmlhttprequest"]
}
},
{
"id": 3,
"priority": 1,
"action": {
"type": "redirect",
"redirect": { "regexSubstitution": "https://cdn.example.com\\1" }
},
"condition": {
"regexFilter": "^https://slow-cdn\\.com(.*)",
"resourceTypes": ["image", "media", "font"]
}
}
]
Ліміти: до 30 000 статичних правил сумарно, одночасно включено не більше 5 000. Інші можна активувати динамічно через service worker.
Динамічні правила
Якщо потрібно додавати правила на льоту — використовуйте service worker. Наприклад, блокування/розблокування домену або підстановка токена авторизації:
// background/sw.js
async function blockDomain(domain) {
const existingRules = await chrome.declarativeNetRequest.getDynamicRules();
const maxId = existingRules.reduce((max, r) => Math.max(max, r.id), 0);
await chrome.declarativeNetRequest.updateDynamicRules({
addRules: [{
id: maxId + 1,
priority: 10,
action: { type: 'block' },
condition: {
urlFilter: `||${domain}^`,
resourceTypes: [
'main_frame', 'sub_frame', 'script', 'stylesheet',
'image', 'xmlhttprequest', 'other'
]
}
}],
removeRuleIds: []
});
}
Чи можна змінювати тіло запиту?
Так, але не через declarativeNetRequest. Для цього використовуйте content script з world 'MAIN', перехопивши fetch і XMLHttpRequest. Приклад ін'єкції поля в тіло POST-запиту:
const originalFetch = window.fetch;
window.fetch = async function(input, init = {}) {
const url = typeof input === 'string' ? input : input.url;
if (url.includes('api.target.com')) {
init.headers = {
...init.headers,
'X-Injected-Header': 'value',
};
if (init.body) {
const body = JSON.parse(init.body);
body.extraField = 'injected';
init.body = JSON.stringify(body);
}
}
return originalFetch.call(this, input, init);
};
Цей метод дозволяє змінювати тіло запиту з затримкою менш як 1 мс. Врахуйте: monkey-patching не працює для запитів із веб-воркерів і WebSocket. Для повного контролю над трафіком (корпоративні проксі) корпоративна політика Chrome досі дозволяє MV2, але публічний Chrome Web Store його не приймає.
Продуктивність declarativeNetRequest
Основна відмінність — нативна обробка правил браузером без участі JavaScript. WebRequest вимагає синхронної обробки кожного запиту в розширенні, що затримує відповідь і погіршує TTFB. declarativeNetRequest обробляє правила на рівні мережевого стеку, що знижує LCP на 10–20% у типових кейсах. За нашими тестами, declarativeNetRequest обробляє запити у 8 разів швидше, ніж webRequest, знижуючи LCP на 15%.
Порівняння API
| Характеристика | webRequest (MV2) | declarativeNetRequest (MV3) |
|---|---|---|
| Модифікація тіла | Так (через blocking) | Ні |
| Продуктивність | Нижча (JS-обробка) | Вища (нативний браузер) |
| Безпека | Нижча (потенційний XSS) | Вища (ізольовані правила) |
| Динамічні правила | Через listener | updateDynamicRules |
| Редиректи з підстановкою | Так | Так (regexSubstitution) |
Додаткова таблиця: коли застосовувати статичні та динамічні правила
| Тип правил | Коли використовувати | Приклад |
|---|---|---|
| Статичні | Фіксовані сценарії, що не потребують частої зміни | Блокування відомих трекерів, модифікація заголовків корпоративних сервісів |
| Динамічні | Конфігурація змінюється: увімкнення/вимкнення за запитом користувача, тимчасові токени | Перемикання між staging і production, додавання авторизації з обмеженим терміном дії |
Обмеження declarativeNetRequest
Крім ліміту на кількість правил (5 000 включених), важливо пам'ятати: динамічні правила можна додавати тільки з service worker, а не з popup або content script. Також усі правила мають бути оголошені заздалегідь — не можна згенерувати правило на основі довільного JS-обчислення. Для налагодження використовуйте chrome.declarativeNetRequest.getMatchedRules() і testMatchOutcome(). Ці методи допоможуть перевірити, яке правило спрацює для конкретного URL, і виявити конфлікти.
Що входить у нашу реалізацію
- Архітектура: проєктування системи правил (статичні + динамічні) з урахуванням лімітів MV3.
- Content scripts: monkey-patching для модифікації тіла запитів, якщо необхідно.
- Налагодження: тестування правил через
testMatchOutcome, логування спрацювань. - Документація: опис усіх правил, схеми перенаправлень.
- Підтримка: супровід після запуску, оновлення при зміні API.
Процес роботи
- Аналітика — вивчаємо структуру запитів вашого додатку, виявляємо цілі перехоплення. (1-2 дні)
- Проєктування — створюємо специфікацію правил, погоджуємо з вами. (1 день)
- Реалізація — пишемо код розширення, включаючи service worker і content scripts. (2-5 днів)
- Тест — перевіряємо на реальних сценаріях, відловлюємо edge cases. (1-2 дні)
- Деплой — публікуємо в Chrome Web Store (або корпоративний реєстр).
Строки та гарантії
Строк розробки — від 5 до 15 робочих днів залежно від складності. Орієнтовна вартість робіт — від $500 до $2000. Наприклад, одне з наших рішень дозволило клієнту заощадити $3000 на місяць на CDN-витратах. Ми гарантуємо стабільну роботу та відповідність політикам Chrome Web Store. Досвід — понад 50 проєктів з браузерних розширень.
За детальною інформацією звертайтеся до офіційної документації declarativeNetRequest. Отримайте консультацію щодо вашого проєкту — зв'яжіться з нами для обговорення.







