Реализация перехвата и модификации HTTP-запросов в браузерном расширении

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация перехвата и модификации HTTP-запросов в браузерном расширении
Сложная
~2-3 рабочих дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация перехвата и модификации HTTP-запросов в браузерном расширении

Перехват HTTP-запросов — одна из самых мощных возможностей расширений. Блокировщики рекламы, VPN-расширения, прокси-инструменты, инжекторы заголовков — всё это строится на chrome.webRequest (MV2) или chrome.declarativeNetRequest (MV3). Переход на MV3 кардинально изменил подход.

MV3: declarativeNetRequest

В Manifest V3 динамическая модификация запросов заменена на декларативные правила. Браузер применяет правила сам, без выполнения JS-кода расширения. Это быстрее и безопаснее, но менее гибко.

{
  "manifest_version": 3,
  "permissions": ["declarativeNetRequest", "declarativeNetRequestWithHostAccess"],
  "host_permissions": ["<all_urls>"],
  "declarative_net_request": {
    "rule_resources": [
      {
        "id": "static-rules",
        "enabled": true,
        "path": "rules/static.json"
      }
    ]
  }
}

Статические правила

Файл 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

Правила можно добавлять и удалять в рантайме:

// 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: []
  });
}

async function unblockDomain(domain) {
  const rules = await chrome.declarativeNetRequest.getDynamicRules();
  const toRemove = rules
    .filter(r => r.condition.urlFilter === `||${domain}^`)
    .map(r => r.id);

  if (toRemove.length > 0) {
    await chrome.declarativeNetRequest.updateDynamicRules({
      addRules: [],
      removeRuleIds: toRemove
    });
  }
}

// Модификация заголовков с динамическим значением
async function setAuthHeader(apiUrl, token) {
  const rules = await chrome.declarativeNetRequest.getDynamicRules();
  const existingRule = rules.find(r =>
    r.condition.urlFilter === apiUrl && r.action.type === 'modifyHeaders'
  );

  const newRule = {
    id: existingRule?.id ?? (rules.reduce((m, r) => Math.max(m, r.id), 0) + 1),
    priority: 5,
    action: {
      type: 'modifyHeaders',
      requestHeaders: [
        { header: 'Authorization', operation: 'set', value: `Bearer ${token}` }
      ]
    },
    condition: {
      urlFilter: apiUrl,
      resourceTypes: ['xmlhttprequest', 'fetch']
    }
  };

  await chrome.declarativeNetRequest.updateDynamicRules({
    addRules: [newRule],
    removeRuleIds: existingRule ? [existingRule.id] : []
  });
}

Наблюдение за запросами: chrome.webRequest (только MV2)

В MV2 можно было перехватывать запросы синхронно и модифицировать их в JS. В MV3 chrome.webRequest доступен только в режиме наблюдения (без блокировки):

// MV2 или MV3 (только чтение, без blocking)
chrome.webRequest.onCompleted.addListener(
  (details) => {
    if (details.statusCode >= 400) {
      logFailedRequest({
        url: details.url,
        status: details.statusCode,
        tabId: details.tabId,
        timestamp: details.timeStamp
      });
    }
  },
  { urls: ['https://api.your-service.com/*'] },
  ['responseHeaders']
);

chrome.webRequest.onBeforeRequest.addListener(
  (details) => {
    // В MV3 — только наблюдение, без blocking
    analytics.track('request', {
      url: new URL(details.url).pathname,
      method: details.method,
      tabId: details.tabId
    });
  },
  { urls: ['<all_urls>'], types: ['xmlhttprequest'] }
);

Перенаправление запросов через declarativeNetRequest

Сложные редиректы с подстановкой:

// Перенаправить запросы к staging на production
await chrome.declarativeNetRequest.updateDynamicRules({
  addRules: [{
    id: 100,
    priority: 1,
    action: {
      type: 'redirect',
      redirect: {
        regexSubstitution: 'https://api.production.com\\1'
      }
    },
    condition: {
      regexFilter: '^https://api\\.staging\\.com(.*)',
      resourceTypes: ['xmlhttprequest', 'fetch']
    }
  }],
  removeRuleIds: []
});

Инъекция заголовков ответа

С разрешением declarativeNetRequestWithHostAccess можно изменять заголовки ответа — например, убирать CORS-ограничения для разработки:

await chrome.declarativeNetRequest.updateDynamicRules({
  addRules: [{
    id: 200,
    priority: 1,
    action: {
      type: 'modifyHeaders',
      responseHeaders: [
        { header: 'Access-Control-Allow-Origin', operation: 'set', value: '*' },
        { header: 'Access-Control-Allow-Methods', operation: 'set', value: 'GET, POST, PUT, DELETE' },
        { header: 'X-Frame-Options', operation: 'remove' }
      ]
    },
    condition: {
      urlFilter: 'https://api.internal.corp/*',
      resourceTypes: ['xmlhttprequest']
    }
  }],
  removeRuleIds: []
});

Отладка правил

// Проверить, какие правила применились к последним запросам
const matched = await chrome.declarativeNetRequest.getMatchedRules({
  tabId: tab.id,
  minTimeStamp: Date.now() - 60000
});
console.log('Применённые правила:', matched.rulesMatchedInfo);

// Проверить, сработает ли правило для конкретного URL
const result = await chrome.declarativeNetRequest.testMatchOutcome({
  url: 'https://analytics.example.com/track',
  type: 'xmlhttprequest',
  method: 'GET',
  tabId: -1,
  initiator: 'https://example.com'
});
console.log('Результат:', result.matchedRule); // null или объект правила

Ограничения MV3 и обходные пути

Нельзя модифицировать тело запроса через declarativeNetRequest. Для этого нужен content script, который перехватывает fetch/XMLHttpRequest через monkey-patching в world: 'MAIN':

// content script с world: 'MAIN'
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);
};

Это работает, но имеет ограничение: monkey-patching не затрагивает запросы из worker-потоков страницы и не перехватывает WebSocket.

Для расширений, которым нужна полная власть над трафиком (корпоративные прокси, инструменты безопасности), MV2 ещё доступен в корпоративной политике Chrome, но не будет поддерживаться в публичном Chrome Web Store.