Пользовательские HTTP-заголовки: контроль запросов
Как задавать пользовательские HTTP-заголовки на уровне движка браузера для согласованной сетевой идентичности во всех сетевых запросах.
Нужна поддерживаемая продуктовая документация?
У этой статьи есть соответствующая страница в центре документации. Используйте docs для каноничного сценария настройки, актуальных флагов и долгосрочной справки.
Введение
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", но со свойствами navigator, специфичными для macOS, создаёт несоответствия, которые системы отслеживания могут коррелировать.
Профили BotBrowser автоматически согласовывают все стандартные заголовки с идентичностью профиля. User-Agent, все заголовки Sec-CH-UA-* и Accept-Language выводятся из настроек браузера, платформы и локали профиля. Пользовательские заголовки, добавленные через --bot-custom-headers, расширяют эту базовую линию, не нарушая стандартный набор заголовков профиля.
Техническая справка
Как браузеры формируют заголовки запросов
Когда браузер отправляет HTTP-запрос, он формирует заголовки из нескольких источников:
- Встроенные заголовки:
User-Agent,Accept,Accept-Encoding,Accept-Languageдобавляются движком браузера на основе внутренних настроек. - Client Hints:
Sec-CH-UA,Sec-CH-UA-Mobile,Sec-CH-UA-Platformотправляются по умолчанию. Высокоэнтропийные подсказки, такие какSec-CH-UA-Full-Version-List, отправляются только когда сервер запрашивает их черезAccept-CH. - Заголовки приложения: заголовки, установленные JavaScript через
fetch()илиXMLHttpRequest. - Заголовки, внедрённые расширениями: заголовки, добавленные браузерными расширениями через API
webRequest.
Порядок и состав этих заголовков создают согласованный паттерн для каждого браузера. Chrome, Edge и Firefox каждый производят разный порядок и комбинации заголовков.
Согласованность заголовков на основе профиля
Когда BotBrowser загружает профиль отпечатка, он настраивает все стандартные заголовки для соответствия идентичности профиля:
User-Agentсоответствует версии браузера и платформе профиляSec-CH-UAсодержит правильные токены марки в правильном порядкеSec-CH-UA-Platformсоответствует операционной системе профиляAccept-Languageотражает настроенную локаль и языковые предпочтения
Эти заголовки задаются на уровне движка и применяются ко всем запросам, включая начальный запрос навигации, загрузку подресурсов и запросы, инициированные JavaScript. Нет временного разрыва, при котором могли бы наблюдаться неправильные заголовки.
Пользовательские заголовки и стандартные заголовки
Пользовательские заголовки (начинающиеся с X- или специфичные для приложения) служат иной цели, чем стандартные заголовки. Они несут данные, специфичные для приложения: токены аутентификации, идентификаторы сессий, маркеры версии приложения или подсказки маршрутизации. Флаг --bot-custom-headers в BotBrowser добавляет эти пользовательские заголовки без модификации стандартных заголовков, управляемых профилем.
Распространённые подходы и их ограничения
Модификация заголовков через расширения
Браузерные расширения могут модифицировать заголовки через API webRequest.onBeforeSendHeaders. Этот подход имеет несколько недостатков:
- Проблемы тайминга: первый запрос (запрос навигации) может быть отправлен до полной регистрации слушателя расширения
- Неполное покрытие: запросы service workers, предварительные CORS-запросы и некоторые внутренние запросы могут не активировать слушатель расширения
- Обнаружимые артефакты: расширения, модифицирующие заголовки, оставляют следы в поверхности API расширений браузера
- Накладные расходы производительности: каждый запрос проходит через JavaScript-обработчик расширения, добавляя задержку
Переопределение заголовков через CDP
Puppeteer и Playwright предоставляют API переопределения заголовков через CDP:
// Puppeteer - limited approach
await page.setExtraHTTPHeaders({ 'X-Custom': 'value' });
Это работает для заголовков уровня страницы, но имеет ограничения:
- Заголовки, установленные таким образом, применяются только к конкретной странице
- Service workers и shared workers могут не получить пользовательские заголовки
- CDP-команда
Network.setExtraHTTPHeadersтребуетNetwork.enable, что само по себе может влиять на фингерпринтинг
JavaScript-заголовки Fetch/XHR
Установка заголовков для отдельных вызовов fetch() или XMLHttpRequest покрывает только запросы, инициированные JavaScript. Запросы навигации, загрузка изображений, получение таблиц стилей и другие запросы, инициированные браузером, не покрываются.
Подход 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 API
- Запросам обновления WebSocket
- Запросам service workers
Нет временных разрывов и пропущенных типов запросов.
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-сессию уровня браузера, а не уровня страницы. Отправка на цель страницы вернёт 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 не включайте кавычки в стиле shell внутрь значения:
// Correct
const headers = { 'X-Custom': 'value', 'X-Auth': 'token' };
args.push('--bot-custom-headers=' + JSON.stringify(headers));
// Wrong - single quotes become part of the JSON value
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();
// Set initial headers
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');
// Update headers mid-session
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 с пользовательскими заголовками убедитесь, что они применяются:
- Откройте страницу, которая отображает заголовки запроса (например, httpbin.org/headers)
- Подтвердите, что ваши пользовательские заголовки присутствуют в ответе
- Проверьте вкладку Network в DevTools, чтобы увидеть заголовки для всех типов запросов
- Убедитесь, что стандартные заголовки (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);
Лучшие практики
-
Используйте --bot-custom-headers для статических заголовков. Если заголовки не меняются в течение сессии, флаг CLI проще, чем CDP.
-
Используйте BotBrowser.setCustomHeaders для динамических заголовков. Когда заголовки нужно менять в ходе сессии (например, ротация токенов аутентификации), используйте CDP-команду.
-
Не переопределяйте заголовки, управляемые профилем. Пользовательские заголовки должны добавлять новые заголовки, а не заменять User-Agent или Sec-CH-UA. Переопределение заголовков профиля создаёт несогласованности.
-
Избегайте распространённых имён заголовков расширений. Заголовки, такие как
X-Forwarded-ForилиX-Real-IP, могут конфликтовать с прокси-инфраструктурой. Используйте имена, специфичные для приложения. -
Тестируйте с httpbin.org/headers. Этот эндпоинт отражает все полученные заголовки, что упрощает проверку конфигурации.
-
Всегда используйте CDP-сессию уровня браузера для setCustomHeaders. Сессии уровня страницы вернут ошибку, потому что команда работает на уровне браузера.
Часто задаваемые вопросы
Применяются ли пользовательские заголовки ко всем запросам или только к навигации? Ко всем запросам. BotBrowser применяет пользовательские заголовки на уровне движка, покрывая навигацию, подресурсы, XHR, Fetch, WebSocket и запросы service workers.
Можно ли задать разные пользовательские заголовки для разных контекстов?
Флаг --bot-custom-headers применяется ко всем контекстам. Для заголовков, специфичных для контекста, используйте CDP-команду BotBrowser.setCustomHeaders, которую можно обновлять между операциями с контекстами.
Влияют ли пользовательские заголовки на отпечаток?
Пользовательские заголовки, не являющиеся частью стандартного набора заголовков браузера (такие как X-Custom-Header), не влияют на отпечаток браузера. Это просто дополнительные заголовки в запросе.
Можно ли удалить стандартный заголовок? BotBrowser не поддерживает удаление стандартных заголовков через пользовательские заголовки. Заголовки, управляемые профилем, всегда включаются для поддержания согласованности отпечатка.
Работает ли --bot-custom-headers с --proxy-server? Да. Пользовательские заголовки добавляются к запросам независимо от того, настроен ли прокси. Прокси видит полный набор заголовков.
Какое максимальное количество пользовательских заголовков можно задать? Конкретного лимита нет. Однако чрезмерно большие наборы заголовков могут увеличить размер запроса и вызвать серверные ограничения.
Можно ли использовать --bot-custom-headers для заголовков Cookie?
Для управления cookies используйте специализированный флаг --bot-cookies. Он обеспечивает правильную обработку cookies с привязкой к домену и сроком истечения.
Итоги
Контроль HTTP-заголовков необходим для поддержания согласованной браузерной идентичности. BotBrowser обеспечивает управление заголовками на уровне движка через профили (для стандартных заголовков), флаг --bot-custom-headers (для статических пользовательских заголовков) и CDP-команду BotBrowser.setCustomHeaders (для динамических заголовков во время выполнения). Вместе эти инструменты гарантируют, что каждый запрос несёт согласованную, полную информацию в заголовках.
По связанным сетевым настройкам смотрите Настройка прокси и Управление User Agent и Client Hints. Для управления идентичностями при работе с несколькими аккаунтами смотрите Изоляция нескольких аккаунтов.
Похожие статьи
Переведите BotBrowser из исследований в продакшн
Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.