Почему HTTP-сервис 1С отвечает не так, как задумано, и как поймать ошибку в коде
Содержание
Чтобы отладить HTTP-сервис в 1С 8.3, включите отладку по протоколу HTTP, в Конфигураторе откройте Отладка → Подключение → Автоматическое подключение и отметьте тип сеансов «HTTP-сервис». После этого точка останова в модуле сервиса срабатывает при каждом внешнем вызове, например из Postman. Если запрос до кода не доходит, ищите причину в публикации, а не в модуле.
Типичная ситуация: интегратор пишет, что ваш метод /hs/api/v1/orders возвращает 500, а у вас в Конфигураторе всё компилируется. Ниже порядок, которым такие случаи разбирают разработчики 1С: от настроек веб-сервера до производительности и тонкостей интеграции.
1. Что проверить до отладки HTTP-сервиса
Большинство «загадочных» ответов сервиса объясняются настройками, а не кодом. Пройдите четыре проверки.
Адрес вызова
Полный адрес собирается из трёх частей:
http://<сервер>/<имя публикации>/hs/<КорневойURL>/<шаблон>
- 🔹
<имя публикации>— то, что указали в поле «Имя» при публикации базы на веб-сервере; - 🔹
hs— фиксированный сегмент для HTTP-сервисов (для веб-сервисов —ws); - 🔹
<КорневойURL>— свойство «Корневой URL» объекта HTTP-сервиса в дереве конфигурации; - 🔹
<шаблон>— шаблон URL, например/orders/{id}.
Регистр в корневом URL и шаблоне имеет значение. Опечатка в одной букве даёт 404.
Публикация HTTP-сервисов
Откройте Администрирование → Публикация на веб-сервере в Конфигураторе. На вкладке HTTP-сервисов должен стоять флажок у нужного сервиса или общий флажок публикации сервисов по умолчанию.
Результат пишется в файл default.vrd в каталоге публикации. Минимальный рабочий фрагмент:
<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
base="/demo"
ib="File="D:\Bases\Demo";">
<httpServices publishByDefault="false">
<service name="API" rootUrl="api" enable="true"
reuseSessions="dontuse" sessionMaxAge="20"/>
</httpServices>
</point>
После добавления нового HTTP-сервиса в конфигурацию публикацию нужно обновить. Новый сервис сам в default.vrd не попадает, если publishByDefault выключен.
Конфигурация базы данных обновлена
Сервис работает с конфигурацией базы данных, а не с основной. Изменили модуль, но не нажали F7 (обновление конфигурации
БД) — веб-сервер выполнит старый код.
Права процесса веб-сервера
В файловом варианте пользователь, от которого работает Apache или IIS, должен иметь права на чтение и запись в каталог базы. Иначе вызов падает до входа в 1С, и ошибка видна только в журнале веб-сервера.
2. Точки останова: отладка через встроенный отладчик 1С
Код HTTP-сервиса выполняется на сервере: в файловом варианте — внутри модуля расширения веб-сервера, в клиент-серверном — в рабочем процессе кластера. Отладчику нужно разрешить подключаться к этим сеансам.
Файловая база через веб-сервер
- В Конфигураторе откройте
Сервис → Параметры → Отладкаи выберите отладку по протоколу HTTP. - Перезапустите Конфигуратор. Отладчик запустит сервер отладки, по умолчанию на порту 1550.
- В
default.vrdвнутри элемента<point>добавьте строку:
<debug enable="true" protocol="http" url="http://localhost:1550"/>
- Перезапустите веб-сервер, чтобы он перечитал публикацию.
- В Конфигураторе:
Отладка → Подключение → Автоматическое подключение, отметьте «HTTP-сервис». - Поставьте точку останова (
F9) в первой строке функции-обработчика метода и отправьте запрос.
Клиент-серверная база
Здесь отладку разрешают на стороне кластера. Службу агента сервера запускают с ключом -debug (для HTTP-отладки дополнительно -http). Дальше — то же автоматическое подключение к сеансам «HTTP-сервис».
Изменение параметров службы требует её перезапуска. Все пользователи сервера потеряют сеансы. Делайте это на тестовом сервере или в согласованное окно, а на рабочем кластере отладку без нужды не держите включённой: она замедляет выполнение кода.
Приём «тонкий обработчик»
Обработчик метода держите коротким: разобрать запрос, вызвать функцию общего модуля, собрать ответ. Вся логика — в общем модуле с серверным контекстом.
Тогда бизнес-логику можно отлаживать из обычной внешней обработки или из тестового клиента, без веб-сервера и Postman. HTTP-уровень остаётся проверить отдельно, и он почти не меняется.
3. Журнал регистрации и логирование запросов
Отладчик хорош, пока ошибка воспроизводится у вас. Для ошибок, которые случаются у контрагента раз в день, нужен лог.
Что писать в журнал регистрации
Функция OrdersGET(Запрос)
Лог = СтрШаблон("%1 %2 | параметры: %3",
Запрос.HTTPМетод,
Запрос.ОтносительныйURL,
СтрСоединить(Запрос.ПараметрыURL, ";"));
ЗаписьЖурналаРегистрации("HTTP.API.Вход",
УровеньЖурналаРегистрации.Информация, , , Лог);
Попытка
Ответ = ОбработкаЗаказов.ПолучитьЗаказ(Запрос.ПараметрыURL.Получить("id"));
Исключение
Инфо = ИнформацияОбОшибке();
ЗаписьЖурналаРегистрации("HTTP.API.Ошибка",
УровеньЖурналаРегистрации.Ошибка, , ,
ПодробноеПредставлениеОшибки(Инфо));
Ответ = Новый HTTPСервисОтвет(500);
Ответ.УстановитьТелоИзСтроки("{""error"":""internal""}",
КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
КонецПопытки;
Возврат Ответ;
КонецФункции
Пояснения к примеру:
- 📌
ПараметрыURL— значения из шаблона ({id}),ПараметрыЗапроса— то, что после?; - 📌 подробное представление ошибки пишите в журнал, а наружу отдавайте короткий текст: стек вызовов внешней системе не нужен;
- 📌 в начале имени события ставьте общий префикс (
HTTP.API), тогда журнал легко отфильтровать по событию.
Не пишите в журнал тело запроса целиком, если там персональные данные или пароли. Журнал видят все администраторы базы.
Где ещё искать следы
| Источник | Что в нём видно | Когда смотреть |
|---|---|---|
| Журнал регистрации базы | Ваши записи, исключения, входы пользователей | Ошибка внутри кода |
Журнал ошибок Apache (error.log) или журнал IIS | Падение модуля, отказ в доступе к каталогу | Запрос не доходит до 1С |
Технологический журнал (logcfg.xml, событие EXCP) | Исключения платформы на сервере | Ошибок нет в журнале регистрации |
4. Проверка HTTP-сервиса в Postman и curl
Postman снимает вопрос «это у нас или у них». Если из Postman всё работает, проблема на стороне вызывающей системы.
Настройка запроса в Postman
- Создайте запрос, выберите метод (
GET,POST), вставьте полный адрес с/hs/. - Вкладка
Authorization→ типBasic Auth, логин и пароль пользователя информационной базы. - Для
POST— вкладкаBody→raw→JSON, вставьте тело. - Проверьте, что Postman добавил заголовок
Content-Type: application/json. - Отправьте запрос и смотрите код ответа, заголовки и тело.
Сохраняйте запросы в коллекцию с переменной {{base}} для адреса. Тогда тот же набор проверок перенастраивается с тестовой базы на рабочую одной строкой.
То же самое через curl
curl -i -u admin:123 ^
-H "Content-Type: application/json" ^
-d "{\"id\": 15}" ^
http://localhost/demo/hs/api/v1/orders
Ключ -i показывает заголовки ответа. Это удобно, когда тело пустое.
Вызов из самой 1С
Для автотестов полезно вызывать собственный сервис кодом:
Соединение = Новый HTTPСоединение("localhost", 80, "admin", "123", , 30);
Запрос = Новый HTTPЗапрос("/demo/hs/api/v1/orders/15");
Ответ = Соединение.Получить(Запрос);
Сообщить(Ответ.КодСостояния);
Сообщить(Ответ.ПолучитьТелоКакСтроку());
Последний параметр конструктора, 30, — таймаут в секундах. Без него зависший сервис подвесит и тестовый клиент.
5. Коды ответа и типовые ошибки HTTP-сервиса 1С
Ещё две ошибки, которые не выглядят как ошибки:
- 🐞 Внешняя система получает JSON с невидимым символом в начале и не может его разобрать. Это BOM. Лечится параметром
ИспользованиеByteOrderMark.НеИспользовать. - 🐞 Метод отвечает 200, но изменения в базе не появились. Обработчик поймал исключение, ничего не записал и вернул «успех». Возвращайте код ошибки явно.
6. Аутентификация и безопасность вызовов
Варианты входа
| Способ | Как работает | Риски |
|---|---|---|
| Basic Auth | Заголовок Authorization: Basic <base64(логин:пароль)> | Пароль читается из трафика без HTTPS |
| Аутентификация ОС | Учётная запись Windows сопоставлена пользователю 1С | Подходит только внутри домена |
Логин и пароль в default.vrd | Атрибуты usr и pwd в элементе <point> | Пароль лежит в файле открытым текстом, вход без проверки для всех |
Последний вариант встречается часто: «чтобы интеграция не просила пароль». Так вы открываете сервис всем, кто знает адрес.
Минимальные правила
- 🔒 Отдельный пользователь под интеграцию, с ролью только на нужные объекты. Не
Администратор. - 🔒 HTTPS на веб-сервере: в Apache — модуль
mod_sslи сертификат. Без него Basic Auth передаёт пароль фактически открытым текстом. - 🔒 Проверка входных данных в обработчике: тип, длина, допустимые значения.
idиз адреса — это строка от чужой системы. - 🔒 Свой токен в заголовке, например
X-Api-Key, если внешняя система не умеет Basic. Читается черезЗапрос.Заголовки.Получить("X-Api-Key").
Ключи соответствия заголовков чувствительны к регистру. Внешняя система может прислать x-api-key строчными буквами. Перед проверкой приведите имена заголовков к одному регистру.
7. Производительность HTTP-сервиса: сеансы, запросы, объём ответа
Когда сервис стабильно отвечает, приходит следующая жалоба: «долго». Порядок разбора такой.
Повторное использование сеансов
По умолчанию каждый вызов создаёт сеанс: вход пользователя, загрузка конфигурации, лицензия. На частых коротких запросах это главная часть времени.
В свойствах HTTP-сервиса есть «Повторное использование сеансов» со значениями «Не использовать», «Использовать», «Автоматически использовать», и «Время жизни сеанса» (по умолчанию 20 секунд). Те же настройки в default.vrd — атрибуты reuseSessions и sessionMaxAge.
При повторном использовании сеанс живёт между вызовами. Значения, сохранённые в параметрах сеанса, могут «перетечь» к следующему запросу. Обнуляйте их явно.
Замер производительности
При подключённом отладчике включите Отладка → Замер производительности, отправьте запрос из Postman и остановите замер. Увидите строки модулей с наибольшим временем. Почти всегда это запрос к базе в цикле или чтение объекта целиком ради одного реквизита.
Что ускоряет ответ
- ⚡ Постраничная выдача: параметры
limitиoffsetв адресе вместо «все документы за год». - ⚡ Один пакетный запрос вместо обращений к реквизитам через точку в цикле.
- ⚡ Тяжёлые операции — в фоновое задание: сервис сразу отвечает
202с номером задачи, а результат забирают отдельным методом. - ⚡ Сжатие на веб-сервере для больших JSON-ответов.
8. Интеграция с внешними системами: где ломается обмен
Сервис прошёл все проверки у вас, но у партнёра не работает. Частые причины:
- 🔸 Браузер и CORS. Фронтенд на JavaScript сначала шлёт запрос
OPTIONS. Добавьте этот метод в шаблон и отвечайте заголовкамиAccess-Control-Allow-Origin,Access-Control-Allow-Methods,Access-Control-Allow-Headers. - 🔸 Даты в JSON. Внешние системы ждут ISO 8601. Задавайте формат при сериализации через
НастройкиСериализацииJSONиФорматДатыJSON.ISO, а не склеивайте дату строкой. - 🔸 Числа. Разделитель групп разрядов в выгрузке ломает парсер. Для ручного формирования строки используйте
Формат(Число, "ЧГ=0; ЧРД=."). - 🔸 Таймауты. Внешняя сторона рвёт соединение через 30 секунд, а ваш код работает 40. В журнале регистрации у вас успех, у них ошибка. Решение — фоновое задание и асинхронный ответ из раздела 7.
- 🔸 Прокси и балансировщик. Между системами стоит nginx, который режет тело больше заданного лимита или меняет заголовки. Сравните, что пришло в
Запрос.Заголовки, с тем, что отправили.
9. Частые вопросы об отладке HTTP-сервисов
Можно ли отлаживать HTTP-сервис без веб-сервера?
Почему точка останова не срабатывает, хотя ответ приходит?
debug в default.vrd и перезапуск веб-сервера после её добавления.Как посмотреть сырое тело запроса, которое прислала внешняя система?
Запрос.ПолучитьТелоКакСтроку() и запишите результат в журнал регистрации. Для двоичных данных — ПолучитьТелоКакДвоичныеДанные().