Отладка HTTP-запросов 1С: от встроенного лога до снифферов
Содержание
Чтобы увидеть, что реально ушло на сервер и что пришло в ответ, не нужны сторонние инструменты: HTTP-запрос в 1С проверяют прямо в коде через объекты HTTPСоединение, HTTPЗапрос и HTTPОтвет. Достаточно вывести КодСостояния, заголовки и тело ответа — и в 8 случаях из 10 причина сбоя интеграции видна сразу.
Снифферы (Fiddler, Wireshark), журнал регистрации и технологический журнал подключают, когда ответ 1С не объясняет проблему: запрос не доходит, рвётся соединение, не проходит проверка сертификата или ломается кодировка. Ниже — методы по возрастанию сложности: начинаем с кода, заканчиваем анализом сетевых пакетов.
Смотрим код состояния и тело ответа в коде 1С
Первый шаг отладки — выполнить запрос вручную и распечатать ответ целиком. В 1С 8.3 за HTTP-обмен отвечают три объекта: HTTPСоединение (канал до сервера), HTTPЗапрос (адрес, заголовки, тело) и HTTPОтвет (то, что вернул сервер).
Соединение = Новый HTTPСоединение("api.example.ru", 443, , , , 30,
Новый ЗащищенноеСоединениеOpenSSL());
Запрос = Новый HTTPЗапрос("/v1/orders");
Запрос.Заголовки.Вставить("Authorization", "Bearer " + Токен);
Запрос.Заголовки.Вставить("Accept", "application/json");
Ответ = Соединение.Получить(Запрос);
Сообщить(СтрШаблон("Код состояния: %1", Ответ.КодСостояния));
Для Каждого Заголовок Из Ответ.Заголовки Цикл
Сообщить(Заголовок.Ключ + ": " + Заголовок.Значение);
КонецЦикла;
Сообщить(Ответ.ПолучитьТелоКакСтроку("UTF-8"));
Главное, на что смотреть — Ответ.КодСостояния. Он сразу делит проблемы на классы:
- 🟢
200,201,204— сервер принял запрос, ошибка (если есть) на стороне разбора ответа. - 🟡
400,422— сервер не понял тело или параметры: проверяйте JSON и обязательные поля. - 🔴
401,403— не прошла авторизация: токен, заголовок, права доступа . - 🔴
404— неверный путь ресурса вHTTPЗапрос. - ⚫
500,502,503— ошибка или перегрузка на стороне сервера-партнёра, ваш код тут ни при чём.
Тело ответа при ошибке почти всегда содержит текст с пояснением — его и читаем через ПолучитьТелоКакСтроку(). Запускать удобно в обработке с кнопкой либо через внешнюю обработку
: так можно менять заголовки и тело, не трогая рабочий механизм обмена.
Чтобы проверить, что именно уходит из 1С, распечатайте сам запрос перед отправкой: Запрос.АдресРесурса, все пары из Запрос.Заголовки и тело через Запрос.ПолучитьТелоКакСтроку(). Прямого «дампа» сырого пакета платформа не даёт, но этих трёх значений хватает, чтобы сверить запрос с документацией API символ в символ. Если тело — файл или картинка, читайте его как ПолучитьТелоКакДвоичныеДанные() и сохраняйте во временный файл для проверки.
Если отправляете POST, тело задают методом Запрос.УстановитьТелоИзСтроки(ТелоJSON), а сам запрос выполняют через Соединение.ОтправитьДляОбработки(Запрос). Для нестандартных методов (PATCH, DELETE) есть универсальный Соединение.ВызватьHTTPМетод("PATCH", Запрос).
Включаем логирование обмена на сервере
Когда обмен идёт в фоне (регламентное задание, веб-сервис, обработчик события), вывести Сообщить() некуда. Тогда запрос и ответ пишут в журнал регистрации — это самый быстрый способ увидеть историю обмена без сторонних программ.
ЗаписьЖурналаРегистрации("Интеграция.HTTP",
УровеньЖурналаРегистрации.Информация, , ,
СтрШаблон("GET %1 → %2%3%4",
Запрос.АдресРесурса,
Ответ.КодСостояния,
Символы.ПС,
Ответ.ПолучитьТелоКакСтроку("UTF-8")));
Смотреть записи: Главное → Журнал регистрации, затем отбор по имени события Интеграция.HTTP. Так по каждому обмену видно время, код ответа и тело — удобно разбирать, почему вчера ночью выгрузка не ушла.
Не пишите в журнал токены авторизации и персональные данные в открытом виде — журнал читают все пользователи с соответствующими правами. Логируйте заголовки без значения Authorization.
Если ошибка возникает ещё до ответа — на уровне сети или OpenSSL — в журнале регистрации её может не быть. Тогда включают технологический журнал: он ловит исключения платформы. Создайте файл logcfg.xml в каталоге conf установленной платформы:
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="C:\v8log" history="24">
<event>
<eq property="name" value="EXCP"/>
</event>
<property name="all"/>
</log>
</config>
Событие EXCP собирает все исключения, включая ошибки установки защищённого соединения и обрыва канала. Логи появятся в каталоге из атрибута location. После отладки файл удаляют — технологический журнал заметно нагружает диск.
На сервере технологический журнал пишется для всего кластера и может быстро заполнить диск. На рабочей базе ограничивайте сбор по времени (атрибут history в часах) и убирайте конфиг сразу после диагностики.
Перехватываем трафик: Fiddler и Wireshark
Код и логи показывают, что получила 1С. Чтобы увидеть фактический пакет на проводе, нужен сниффер. Два инструмента решают разные задачи.
Fiddler — прокси для HTTP/HTTPS. Он встаёт между 1С и сервером, расшифровывает HTTPS и показывает запрос и ответ в читаемом виде: URL, метод, все заголовки, тело. Это идеальный инструмент, когда сомневаетесь, что именно уходит из 1С.
Чтобы направить обмен через Fiddler:
- Запустите Fiddler — по умолчанию он слушает порт
8888на127.0.0.1. - Включите расшифровку HTTPS:
Tools → Options → HTTPS → Decrypt HTTPS traffic. - В 1С пропишите прокси в соединении: седьмой-восьмой параметры
HTTPСоединениепринимают объектИнтернетПрокси.
Прокси = Новый ИнтернетПрокси;
Прокси.Установить("http", "127.0.0.1", 8888);
Прокси.Установить("https", "127.0.0.1", 8888);
Соединение = Новый HTTPСоединение("api.example.ru", 443, , , Прокси, 30,
Новый ЗащищенноеСоединениеOpenSSL());
Нюанс: 1С проверяет сертификат через OpenSSL, а Fiddler подменяет его своим. Поэтому корневой сертификат Fiddler нужно передать в ЗащищенноеСоединениеOpenSSL как доверенный, иначе получите ошибку проверки сертификата. Для разовой диагностики проще использовать отдельную тестовую базу.
Wireshark работает на уровне сетевых пакетов. Расшифровать HTTPS без ключей он не сможет, зато покажет то, что скрыто от Fiddler: дошёл ли TCP-пакет до сервера, как прошло SSL-рукопожатие, был ли RST (сброс соединения), сколько длились ответы. Полезные фильтры:
ip.addr == 203.0.113.10— весь обмен с конкретным сервером.tcp.port == 443 && tcp.flags.reset == 1— где рвётся соединение.tls.handshake— этапы установки защищённого канала.
Правило простое: не проходит рукопожатие или рвётся TCP — это Wireshark; запрос доходит, но сервер отвечает не так — это Fiddler.
Диагностируем ошибки SSL и сертификатов
Обмен по HTTPS в 1С идёт через библиотеку OpenSSL. Типичные тексты ошибок: Ошибка работы с OpenSSL, удаленный узел не прошел проверку или unable to get local issuer certificate. Все они означают одно: платформа не смогла построить доверенную цепочку до сертификата сервера.
Частые причины:
- 🔸 Сервер отдаёт самоподписанный сертификат или неполную цепочку (нет промежуточного сертификата УЦ).
- 🔸 На сервере 1С нет корневого сертификата нужного удостоверяющего центра.
- 🔸 Истёк срок действия сертификата сервера — проверяется в браузере по тому же адресу.
- 🔸 Сервер требует клиентский сертификат (двусторонний TLS), а 1С его не предъявляет.
Решение — передать недостающие сертификаты в конструктор защищённого соединения. Первый параметр ЗащищенноеСоединениеOpenSSL — клиентский сертификат, второй — хранилище доверенных сертификатов удостоверяющих центров:
СертификатыУЦ = Новый СертификатыУдостоверяющихЦентровФайл("C:\certs\ca-bundle.pem");
Защита = Новый ЗащищенноеСоединениеOpenSSL(, СертификатыУЦ);
Соединение = Новый HTTPСоединение("api.example.ru", 443, , , , 30, Защита);
Быстрая проверка сертификата без 1С: откройте адрес API в браузере и посмотрите цепочку в свойствах замка, либо выполните в консоли openssl s_client -connect api.example.ru:443. Если браузер и s_client ругаются — проблема на стороне сервера, а не 1С.
Отдельно: ошибка проверки сертификата при включённом Fiddler — это не проблема сервера, а именно подмена сертификата прокси. Выключите Fiddler и проверьте, пропадает ли ошибка.
Проверяем таймауты и скорость сети
Если обмен «подвисает» и регламентное задание висит часами, причина почти всегда в таймауте. Параметр таймаута (в секундах) задаётся при создании соединения — это предпоследний позиционный параметр HTTPСоединение.
// 60 секунд на операцию; без явного значения платформа может ждать очень долго
Соединение = Новый HTTPСоединение("api.example.ru", 443, , , , 60,
Новый ЗащищенноеСоединениеOpenSSL());
Всегда задавайте таймаут явно в фоновых обменах. Иначе один зависший запрос блокирует сеанс, а на сервере — ещё и занятый рабочий процесс.
Как понять, где теряется время:
| Симптом | Что проверить | Чем смотреть |
|---|---|---|
| Долгое подключение | DNS, доступность хоста, firewall | ping, tracert, Wireshark |
| Долгое рукопожатие TLS | медленный УЦ, проверка отзыва | Wireshark (tls.handshake) |
| Долгий ответ сервера | нагрузка на партнёре, тяжёлый запрос | время в журнале регистрации |
| Случайные обрывы | потери пакетов, нестабильный канал | Wireshark (tcp.analysis.retransmission) |
Если запрос стабильно падает по таймауту ровно на красивой цифре (30, 60 секунд) — лимит режет не ваша 1С, а прокси или шлюз между вами и сервером. Увеличивать таймаут в коде бесполезно, нужно разбираться с сетевым оборудованием.
Ещё одна тонкость — разделяйте таймаут подключения и таймаут ответа. Если хост в принципе недоступен, запрос упадёт быстро, на этапе установки соединения. А вот когда соединение установлено, но сервер долго считает ответ, запрос будет честно ждать весь отведённый лимит. Поэтому для тяжёлых выгрузок таймаут поднимают осознанно, а для частых мелких запросов, наоборот, занижают — чтобы один недоступный партнёр не тормозил всю очередь обмена.
Разбираем заголовки и кодировки
Две классические беды интеграций — сервер не понимает тело из-за заголовка Content-Type и в ответе приходят «кракозябры» из-за кодировки.
Заголовки. Для JSON сервер почти всегда ждёт точный Content-Type. Если его не указать, тело может уйти как обычный текст, и сервер вернёт 400 или 415:
Запрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Запрос.УстановитьТелоИзСтроки(ТелоJSON, ТекстовоеКодирование.UTF8,
ИспользованиеByteOrderMark.НеИспользовать);
Обратите внимание на НеИспользовать для BOM: метка порядка байтов в начале строки ломает разбор JSON на многих серверах — тело валидное, а парсер партнёра падает. Отключение BOM убирает невидимые символы в начале.
Кодировки. ПолучитьТелоКакСтроку() без параметра пытается определить кодировку по заголовку ответа. Если сервер его не прислал, а тело — в windows-1251, строка превратится в нечитаемый набор символов. Укажите кодировку явно:
// сервер вернул windows-1251, а не UTF-8
Текст = Ответ.ПолучитьТелоКакСтроку("windows-1251");
Какую кодировку прислал сервер, видно в заголовке Content-Type ответа — его вы уже распечатали на первом шаге. Если заголовка нет, а текст с «кракозябрами» — переберите UTF-8 и windows-1251, одна из них даст читаемый результат.
Частые ошибки при отладке интеграции
Большинство «зависших» интеграций ломаются на одних и тех же местах. Быстрая диагностика по симптому:
Authorization не дошёл или содержит лишний пробел либо перенос строки. Распечатайте Запрос.Заголовки перед отправкой и сверьте значение символ в символ.Content-Type ответа и укажите кодировку в ПолучитьТелоКакСтроку() явно.ИспользованиеByteOrderMark.НеИспользовать и проверьте Content-Type запроса.ping/tracert и Wireshark; увеличивать таймаут в коде при обрыве на сетевом шлюзе бесполезно.Отдельно про диагностику «вслепую»: не меняйте сразу несколько параметров. Зафиксируйте один рабочий запрос (например, через Fiddler или curl), добейтесь от него 200, а затем по одному переносите заголовки и тело в код 1С, сверяя результат.
Частые вопросы
Можно ли отладить HTTP-запрос в 1С без сторонних программ?
КодСостояния, заголовков и тела HTTPОтвет прямо в коде, а для фоновых обменов — записи запроса и ответа в журнал регистрации. Снифферы нужны только когда запрос не доходит до сервера или рвётся соединение.Почему Fiddler показывает ошибку сертификата, а без него всё работает?
Чем Wireshark отличается от Fiddler для отладки 1С?
Как узнать, в какой кодировке сервер прислал ответ?
Content-Type ответа (charset=...). Распечатайте заголовки HTTPОтвет и передайте нужную кодировку в ПолучитьТелоКакСтроку(). Если заголовка нет — переберите UTF-8 и windows-1251.Где в 1С задаётся таймаут HTTP-запроса?
HTTPСоединение отдельным параметром в секундах. В фоновых обменах его задают всегда, иначе зависший запрос блокирует сеанс и рабочий процесс сервера.