Назад к блогу
Сеть

Пользовательские HTTP-заголовки: управление заголовками запросов с BotBrowser

Узнайте, как устанавливать пользовательские HTTP-заголовки на уровне движка браузера с помощью флага --bot-custom-headers и CDP API BotBrowser для согласованной идентичности запросов.

Введение

HTTP-заголовки присутствуют в каждом запросе, который отправляет ваш браузер. Заголовки вроде User-Agent, Accept-Language, Sec-CH-UA и Referer составляют значительную часть сетевой идентичности браузера. Когда эти заголовки не соответствуют вашему профилю отпечатка, или когда нужно внедрить прикладные заголовки для аутентификации и маршрутизации, стандартные браузерные API оказываются недостаточными.

BotBrowser предоставляет управление заголовками на уровне движка через флаг --bot-custom-headers и CDP-команду BotBrowser.setCustomHeaders. В отличие от расширений, которые перехватывают запросы уже после их формирования, BotBrowser изменяет заголовки до того, как запрос покинет сетевой стек браузера, охватывая все типы запросов без временных разрывов.

Влияние на приватность

HTTP-заголовки раскрывают много информации о окружении браузера. Строка User-Agent идентифицирует версию браузера и ОС. Accept-Language раскрывает языковые предпочтения и, косвенно, вероятный регион. Client Hints (Sec-CH-UA, Sec-CH-UA-Platform, Sec-CH-UA-Mobile) дают структурированные данные о бренде браузера, платформе и типе устройства.

Если эти заголовки не согласованы с другими аспектами отпечатка, возникает заметная несогласованность. Браузер, сообщающий Accept-Language: de-DE, но находящийся в часовом поясе США, или Sec-CH-UA-Platform: "Windows", но имеющий macOS-специфичные navigator-свойства, создаёт расхождения, которые системы трекинга могут коррелировать.

Профили BotBrowser автоматически выравнивают все стандартные заголовки с идентичностью профиля. User-Agent, все Sec-CH-UA-* и Accept-Language берутся из настроек браузера, платформы и локали профиля. Пользовательские заголовки, добавленные через --bot-custom-headers, расширяют эту базу, не нарушая стандартного набора заголовков.

Технический фон

Как браузеры формируют заголовки

При отправке HTTP-запроса браузер формирует заголовки из нескольких источников:

  1. Встроенные заголовки: User-Agent, Accept, Accept-Encoding, Accept-Language добавляются движком на основе внутренних настроек.
  2. Client Hints: Sec-CH-UA, Sec-CH-UA-Mobile, Sec-CH-UA-Platform отправляются по умолчанию. Высокоэнропийные hints, такие как Sec-CH-UA-Full-Version-List, отправляются лишь по запросу сервера через Accept-CH.
  3. Прикладные заголовки: заголовки, выставленные JavaScript через fetch() или XMLHttpRequest.
  4. Заголовки от расширений: заголовки, добавленные расширениями через API webRequest.

Порядок и состав этих заголовков создают устойчивый паттерн для каждого браузера. Chrome, Edge и Firefox имеют различия в порядке и комбинациях заголовков.

Согласованность на основе профиля

Когда BotBrowser загружает профиль отпечатка, он настраивает все стандартные заголовки в соответствии с идентичностью профиля:

  • User-Agent соответствует версии браузера и платформе в профиле
  • Sec-CH-UA содержит корректные бренд-токены в нужном порядке
  • Sec-CH-UA-Platform совпадает с ОС профиля
  • Accept-Language отражает locale и языковые предпочтения

Эти заголовки задаются на уровне движка и применяются ко всем запросам: навигации, подресурсам и JS-запросам. Временной разрыва, при котором могли бы наблюдаться некорректные заголовки, нет.

Пользовательские заголовки vs стандартные

Пользовательские заголовки (например, начинающиеся с X- или специфичные для приложения) служат для передачи прикладных данных: токенов аутентификации, идентификаторов сессий, маркеров версии или подсказок маршрутизации. Флаг --bot-custom-headers добавляет такие заголовки, не изменяя управляемые профилем стандартные заголовки.

Header Sources in BotBrowser Profile (Automatic) User-Agent, Sec-CH-UA-* Accept-Language CLI Override --bot-config-locale --bot-config-languages Custom Headers --bot-custom-headers BotBrowser.setCustomHeaders Final Request Headers All sources merge at the engine level before the request is sent

Распространённые подходы и их ограничения

Модификация заголовков через расширения

Расширения могут изменять заголовки через webRequest.onBeforeSendHeaders. У этого подхода есть недостатки:

  • Проблемы c таймингом: первая навигационная заявка может быть отправлена до регистрации слушателя расширения
  • Неполное покрытие: запросы service worker, предзапросы CORS и некоторые внутренние запросы могут не вызвать слушатель
  • Обнаружимые артефакты: расширения, модифицирующие заголовки, оставляют следы в API расширений
  • Накладные расходы на производительность: каждый запрос проходит через JS-обработчик расширения, добавляя задержки

Переопределения через CDP

Puppeteer и Playwright предоставляют API для переопределения заголовков через CDP:

// Puppeteer - limited approach
await page.setExtraHTTPHeaders({ 'X-Custom': 'value' });

Это работает на уровне страницы, но имеет ограничения:

  • Заголовки, установленные этим способом, применяются только к конкретной странице
  • Service workers и shared workers могут не получать эти заголовки
  • Команда CDP Network.setExtraHTTPHeaders требует Network.enable, что само по себе может влиять на отпечаток

Заголовки Fetch/XHR в JavaScript

Установка заголовков в отдельных fetch() или XMLHttpRequest покрывает только запросы, инициированные JS. Навигационные запросы, загрузки изображений, стилей и другие запросы браузера не охватываются.

Подход BotBrowser

Флаг --bot-custom-headers

Флаг --bot-custom-headers BotBrowser (PRO) внедряет пользовательские заголовки на уровне движка:

chrome --bot-profile="/path/to/profile.enc" \
       --bot-custom-headers='{"X-Custom-Header":"value","X-Auth-Token":"abc123"}' \
       --user-data-dir="$(mktemp -d)"

Поскольку модификация происходит внутри сетевого стека Chromium, пользовательские заголовки добавляются к:

  • Инициализационной навигации
  • Запросам подресурсов (изображения, скрипты, стили, шрифты)
  • XHR и Fetch запросам
  • WebSocket upgrade запросам
  • Запросам Service Worker

Нет временных разрывов и пропущенных типов запросов.

CDP-команда BotBrowser.setCustomHeaders

Для управления заголовками в рантайме BotBrowser предоставляет CDP-команду, которую можно отправить в сессию уровня браузера:

Puppeteer:

const cdpSession = await browser.target().createCDPSession();
await cdpSession.send('BotBrowser.setCustomHeaders', {
  headers: { 'x-requested-with': 'com.example.app' }
});

Playwright:

const cdpSession = await browser.newBrowserCDPSession();
await cdpSession.send('BotBrowser.setCustomHeaders', {
  headers: { 'x-requested-with': 'com.example.app' }
});

Важно: эту команду нужно отправлять в сессию CDP уровня браузера, а не в сессию страницы. Отправка в target страницы вернёт ProtocolError: 'BotBrowser.setCustomHeaders' wasn't found.

Конфигурация на уровне профиля

Пользовательские заголовки также можно задать в конфигурации профиля через configs.customHeaders. Это полезно, если нужно включить заголовки в профиль, а не задавать их при запуске.

Конфигурация и использование

CLI-пример с пользовательскими заголовками

chrome --bot-profile="/path/to/profile.enc" \
       --bot-custom-headers='{"X-App-Version":"2.1.0","X-Session-ID":"sess_abc123"}' \
       --proxy-server=socks5://user:pass@proxy:1080 \
       --user-data-dir="$(mktemp -d)"

Интеграция с Playwright

const { chromium } = require('playwright-core');

(async () => {
  const browser = await chromium.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/path/to/profile.enc',
      '--bot-custom-headers={"X-Auth":"token123","X-Client":"webapp"}',
    ],
    headless: true,
  });

  const context = await browser.newContext();
  const page = await context.newPage();
  await page.goto('https://example.com');
  await browser.close();
})();

Интеграция с Puppeteer

const puppeteer = require('puppeteer-core');

(async () => {
  const browser = await puppeteer.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/path/to/profile.enc',
      '--bot-custom-headers={"X-Auth":"token123"}',
    ],
    headless: true,
    defaultViewport: null,
  });

  const page = await browser.newPage();
  await page.goto('https://example.com');
  await browser.close();
})();

Кавычки в JavaScript

При передаче --bot-custom-headers из JavaScript не включайте оболочное цитирование внутри значения:

// Правильно
const headers = { 'X-Custom': 'value', 'X-Auth': 'token' };
args.push('--bot-custom-headers=' + JSON.stringify(headers));

// Неправильно - одинарные кавычки станут частью JSON-значения
args.push(`--bot-custom-headers='${JSON.stringify(headers)}'`);

Обновления заголовков в рантайме через CDP

Для рабочих потоков, которым нужно менять заголовки во время сессии:

const { chromium } = require('playwright-core');

(async () => {
  const browser = await chromium.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/path/to/profile.enc',
    ],
    headless: true,
  });

  const cdpSession = await browser.newBrowserCDPSession();

  // Установить начальные заголовки
  await cdpSession.send('BotBrowser.setCustomHeaders', {
    headers: { 'x-requested-with': 'com.example.app' }
  });

  const page = await (await browser.newContext()).newPage();
  await page.goto('https://example.com');

  // Обновить заголовки в сессии
  await cdpSession.send('BotBrowser.setCustomHeaders', {
    headers: { 'x-requested-with': 'com.example.app', 'x-session': 'refreshed' }
  });

  await page.goto('https://example.com/dashboard');
  await browser.close();
})();

Верификация

После запуска BotBrowser с пользовательскими заголовками проверьте их применение:

  1. Откройте страницу, которая возвращает заголовки запроса (например https://httpbin.org/headers)
  2. Убедитесь, что ваши пользовательские заголовки присутствуют в ответе
  3. Проверьте вкладку Network в DevTools, чтобы увидеть заголовки во всех типах запросов
  4. Убедитесь, что стандартные заголовки (User-Agent, Sec-CH-UA) по-прежнему соответствуют профилю
const page = await context.newPage();
await page.goto('https://httpbin.org/headers');
const headersText = await page.textContent('body');
console.log('Request headers:', headersText);

Лучшие практики

  1. Используйте --bot-custom-headers для статических заголовков. Если заголовки не меняются в течение сессии, флаг CLI проще, чем CDP.

  2. Используйте BotBrowser.setCustomHeaders для динамических заголовков. Для ротации токенов и других runtime изменений используйте CDP.

  3. Не переопределяйте заголовки, управляемые профилем. Пользовательские заголовки должны дополнять, а не заменять User-Agent или Sec-CH-UA.

  4. Избегайте распространённых имён заголовков расширений. Заголовки вроде X-Forwarded-For или X-Real-IP могут конфликтовать с инфраструктурой прокси; используйте имена, специфичные для приложения.

  5. Тестируйте с httpbin.org/headers. Этот endpoint возвращает полученные заголовки, облегчая валидацию.

  6. Всегда используйте сессию CDP уровня браузера для setCustomHeaders. Сессии уровня страницы вернут ошибку.

Часто задаваемые вопросы

Применяются ли пользовательские заголовки ко всем запросам или только к навигации? Применяются ко всем запросам. BotBrowser добавляет пользовательские заголовки на уровне движка, охватывая навигацию, подресурсы, XHR, Fetch, WebSocket и Service Worker.

Можно ли задать разные пользовательские заголовки для каждого контекста? Флаг --bot-custom-headers применяется ко всем контекстам. Для заголовков по контексту используйте BotBrowser.setCustomHeaders и обновляйте их между операциями контекста.

Влияют ли пользовательские заголовки на отпечаток? Пользовательские заголовки, не входящие в стандартный набор (например X-Custom-Header), не влияют на отпечаток браузера; это просто дополнительные поля в запросе.

Можно ли удалить стандартный заголовок? BotBrowser не позволяет удалять стандартные заголовки через пользовательские заголовки. Заголовки, управляемые профилем, всегда включены для сохранения согласованности отпечатка.

Работает ли --bot-custom-headers с --proxy-server? Да. Заголовки добавляются независимо от настройки прокси; прокси увидит полный набор заголовков.

Есть ли ограничение на количество пользовательских заголовков? Нет явного лимита. Однако слишком большой набор заголовков может увеличить размер запроса и вызвать серверные ограничения.

Можно ли использовать --bot-custom-headers для Cookie-заголовков? Для управления cookie используйте специальный флаг --bot-cookies. Он корректно обрабатывает области доменов и срок действия.

Резюме

Управление HTTP-заголовками важно для поддержания согласованной идентичности браузера. BotBrowser предоставляет управление заголовками на уровне движка через профили (для стандартных заголовков), флаг --bot-custom-headers (для статических пользовательских заголовков) и CDP-команду BotBrowser.setCustomHeaders (для динамических заголовков). В совокупности эти инструменты гарантируют, что каждый запрос несёт полную и согласованную информацию заголовков.

Связанные темы: Proxy Configuration и User Agent Control and Client Hints. Для управления идентичностями нескольких аккаунтов смотрите Multi-Account Browser Isolation.

title: "Пользовательские HTTP-заголовки: управление заголовками запросов в BotBrowser" description: "Узнайте, как устанавливать пользовательские HTTP-заголовки с помощью флага --bot-custom-headers в BotBrowser для согласованной идентификации браузера." date: "2025-09-23" locale: ru category: network tags: ["http-headers", "custom-headers", "network", "privacy", "request"] published: true

Почему контроль заголовков важен

HTTP-заголовки, такие как User-Agent, Accept-Language и Sec-CH-UA, являются частью идентификации вашего браузера. Когда эти заголовки не согласованы с остальным профилем фингерпринта, несоответствие заметно. BotBrowser автоматически управляет всеми стандартными заголовками через профили и позволяет добавлять пользовательские заголовки на уровне движка.

Согласованность заголовков на основе профиля

При загрузке профиля фингерпринта с --bot-profile BotBrowser автоматически согласовывает все стандартные заголовки с идентификацией профиля. Заголовки User-Agent, Sec-CH-UA и Accept-Language совпадают с настройками браузера, платформы и локали профиля.

chrome --bot-profile="/path/to/profile.enc" \
       --bot-config-locale="de-DE" \
       --bot-config-languages="de-DE,de,en-US,en" \
       --user-data-dir="$(mktemp -d)"

Это гарантирует совпадение Accept-Language с настроенной локалью и согласованность всех заголовков Client Hints с профилем.

Добавление пользовательских заголовков

Флаг --bot-custom-headers позволяет устанавливать дополнительные HTTP-заголовки на уровне движка браузера:

chrome --bot-profile="/path/to/profile.enc" \
       --bot-custom-headers='{"X-Custom-Header":"value","Another-Header":"value2"}' \
       --user-data-dir="$(mktemp -d)"

Варианты использования пользовательских заголовков включают токены аутентификации, идентификаторы для конкретных приложений и заголовки контроля конфиденциальности.

Модификация на уровне движка

Поскольку BotBrowser модифицирует заголовки на уровне движка Chromium, изменения применяются ко всем запросам:

  • Начальные загрузки страниц
  • Запросы подресурсов (изображения, скрипты, стили)
  • Запросы XHR и Fetch API
  • Запросы обновления WebSocket

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

Пример Puppeteer

const puppeteer = require('puppeteer-core');

const browser = await puppeteer.launch({
  executablePath: '/path/to/botbrowser/chrome',
  args: [
    '--bot-profile=/path/to/profile.enc',
    '--bot-custom-headers={"X-Auth":"token123"}',
  ],
  headless: true,
  defaultViewport: null,
});

const page = await browser.newPage();
await page.goto('https://example.com');
await browser.close();

Проверка

После запуска BotBrowser с пользовательскими заголовками:

  1. Откройте DevTools и проверьте вкладку Network для исходящих заголовков
  2. Убедитесь, что пользовательские заголовки присутствуют во всех типах запросов
  3. Подтвердите, что стандартные заголовки совпадают с загруженным профилем

Начало работы

  1. Скачайте BotBrowser с GitHub
  2. Загрузите профиль фингерпринта с --bot-profile
  3. Добавьте пользовательские заголовки с --bot-custom-headers
  4. Проверьте согласованность заголовков во всех типах запросов
#http-headers#custom-headers#network#privacy#request