Входящий HTTP-запрос в 1С 8.3: от шаблона URL до ответа JSON
Содержание
Чтобы обработать запрос в 1С, создайте HTTP-сервис в ветке Общие → HTTP-сервисы, задайте шаблон URL и метод, а в процедуре-обработчике прочитайте объект HTTPСервисЗапрос и верните HTTPСервисОтвет с кодом состояния. Всё, что не вернуло ответ или упало исключением, клиент увидит как код 500.
Частое заблуждение — считать, что 1С «сама» разберёт JSON и проверит данные. Нет: платформа только сопоставит адрес с шаблоном и проверит пользователя. Разбор тела, проверки, коды ошибок и журнал — работа разработчика. Ниже по шагам, с кодом, который можно взять за основу.
Как устроен HTTP-сервис в 1С и куда приходит запрос
HTTP-сервис — объект метаданных конфигурации. У него три уровня:
- 🌐 Корневой URL — свойство сервиса, например
api. Это первая часть адреса. - 🧩 Шаблоны URL — пути внутри сервиса:
/orders,/orders/{id}. В фигурных скобках — параметры. - ⚙️ Методы — у каждого шаблона свой набор: GET, POST, PUT, DELETE и другие. Каждому методу назначается функция-обработчик в модуле сервиса.
Полный адрес после публикации выглядит так:
http://сервер/ИмяПубликации/hs/КорневойURL/шаблон
http://srv01/trade/hs/api/orders/000123
Сегмент hs добавляет платформа — он отличает HTTP-сервисы от веб-сервисов (ws) и OData.
Создание сервиса в конфигураторе
- В дереве конфигурации откройте
Общие → HTTP-сервисыи добавьте новый объект. - Заполните
Корневой URL, напримерapi. - На вкладке шаблонов добавьте шаблон
/orders/{id}. - Внутри шаблона добавьте метод
GET. - В свойствах метода нажмите кнопку открытия у поля
Обработчик— конфигуратор создаст в модуле функцию с параметромЗапрос.
Публикация на веб-сервере
Сервис работает только через веб-сервер (Apache или IIS) с модулем расширения 1С. Публикуют его из конфигуратора: Администрирование → Публикация на веб-сервере. На вкладке HTTP-сервисов должен стоять флажок публикации, а нужный сервис — отмечен.
Публиковать можно и файловую базу. Для отладки этого достаточно: локальный Apache и файловая копия рабочей базы.
Алгоритм обработки входящего запроса в 1С
Хороший обработчик всегда идёт по одному порядку. Отступление от него — главный источник «плавающих» ошибок.
- Проверить метод и параметры адреса.
- Прочитать тело и разобрать формат.
- Проверить данные: обязательные поля, типы, существование объектов.
- Выполнить действие: найти, создать, изменить.
- Сформировать ответ с кодом и телом.
Всё, кроме пятого шага, оборачивается в Попытка … Исключение.
Что лежит в объекте HTTPСервисЗапрос
| Свойство или метод | Что содержит |
|---|---|
HTTPМетод | Строка: GET, POST и т. д. |
ПараметрыURL | Значения из фигурных скобок шаблона (id) |
ПараметрыЗапроса | Параметры после ?: ?limit=50&page=2 |
Заголовки | Заголовки запроса, например Content-Type |
ОтносительныйURL | Путь после корневого URL |
ПолучитьТелоКакСтроку() | Тело текстом |
ПолучитьТелоКакДвоичныеДанные() | Тело для файлов и картинок |
Чтение параметров и тела
Параметры адреса и строки запроса читайте через Получить(): если ключа нет, вернётся Неопределено, а не исключение.
Функция ЗаказGET(Запрос)
Номер = Запрос.ПараметрыURL.Получить("id");
Лимит = Запрос.ПараметрыЗапроса.Получить("limit");
Если Не ЗначениеЗаполнено(Номер) Тогда
Возврат ОтветОшибка(400, "Не указан номер заказа");
КонецЕсли;
// поиск и формирование ответа
// ...
КонецФункции
Тело POST-запроса с JSON разбирают так:
Функция ЗаказыPOST(Запрос)
Тело = Запрос.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
Если ПустаяСтрока(Тело) Тогда
Возврат ОтветОшибка(400, "Пустое тело запроса");
КонецЕсли;
Попытка
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Тело);
Данные = ПрочитатьJSON(Чтение, Истина);
Чтение.Закрыть();
Исключение
Возврат ОтветОшибка(400, "Некорректный JSON");
КонецПопытки;
Если Данные.Получить("customer") = Неопределено Тогда
Возврат ОтветОшибка(422, "Не заполнено поле customer");
КонецЕсли;
// создание документа
// ...
КонецФункции
Второй параметр ПрочитатьJSON(Чтение, Истина) возвращает Соответствие вместо Структура. Это обязательно для внешних данных: ключ вида order-id или 1c_code в структуру не ляжет, и чтение упадёт.
Как сформировать ответ клиенту
Ответ — объект HTTPСервисОтвет. Первый параметр конструктора — код состояния.
Функция ОтветJSON(КодСостояния, Данные)
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, Данные);
Текст = Запись.Закрыть();
Ответ = Новый HTTPСервисОтвет(КодСостояния);
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Ответ.УстановитьТелоИзСтроки(Текст, КодировкаТекста.UTF8,
ИспользованиеByteOrderMark.НеИспользовать);
Возврат Ответ;
КонецФункции
Функция ОтветОшибка(КодСостояния, Сообщение)
Данные = Новый Структура("error", Сообщение);
Возврат ОтветJSON(КодСостояния, Данные);
КонецФункции
Две детали, на которых спотыкаются чаще всего:
- 🔤 BOM. Без
ИспользованиеByteOrderMark.НеИспользоватьв начало тела может попасть метка порядка байтов. Часть клиентов на JavaScript и PHP после этого не разбирает JSON. - 🔗 Ссылки.
ЗаписатьJSONне сериализует ссылки на справочники и документы. Перед записью превращайте их в строку: код, номер илиСтрока(Ссылка.УникальныйИдентификатор()).
Какие коды состояния возвращать
| Код | Когда | Пример |
|---|---|---|
| 200 | Данные найдены и отданы | GET заказа |
| 201 | Объект создан | POST нового заказа |
| 202 | Принято, обработка позже | Запуск фонового задания |
| 400 | Запрос сломан | Невалидный JSON, нет параметра |
| 401 | Не прошла авторизация | Неверный логин (отдаёт сама платформа) |
| 403 | Нет прав на действие | Пользователь без нужной роли |
| 404 | Объект не найден | Заказ с таким номером отсутствует |
| 409 | Конфликт | Документ уже проведён или заблокирован |
| 422 | Данные не прошли проверку | Нет обязательного поля |
| 500 | Ошибка на стороне 1С | Исключение при записи |
Если путь не совпал ни с одним шаблоном, платформа сама вернёт 404 — ваш код даже не вызовется.
Обработка ошибок и исключений в HTTP-сервисе
Необработанное исключение 1С превращает в ответ 500, а в тело кладёт текст ошибки. Для внешнего клиента это плохо дважды: он не понимает, что делать, и видит внутренние имена объектов.
Правильная схема — перехватить исключение, записать подробности в журнал регистрации, а клиенту вернуть короткое сообщение:
Попытка
НачатьТранзакцию();
СоздатьЗаказ(Данные);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
Подробно = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации("HTTPСервис.Заказы",
УровеньЖурналаРегистрации.Ошибка, , , Подробно);
Возврат ОтветОшибка(500, "Не удалось создать заказ. Обратитесь к администратору");
КонецПопытки;
Разделяйте ошибки клиента и свои. Нет поля, неверный формат даты, неизвестный код товара — это 400 или 422 с понятным текстом. Сбой записи, блокировка, нехватка прав у служебного пользователя — 500 или 409.
Не возвращайте 200 с текстом {"error": "..."}. Интегратор будет проверять только код и примет ошибку за успех.
Повторные запросы
Клиенты при таймауте часто повторяют POST. Без защиты в базе появятся два одинаковых заказа. Приём практиков — ключ идемпотентности: клиент передаёт свой номер заявки, а сервис перед созданием ищет документ с таким внешним номером. Нашёл — возвращает 200 с уже созданным объектом, а не создаёт второй.
Авторизация и безопасность запросов к 1С
По умолчанию HTTP-сервис требует Basic-авторизацию пользователем информационной базы. Логин и пароль клиент передаёт в заголовке Authorization, 1С сверяет их со списком пользователей. Не прошла проверка — платформа сама отвечает 401.
Что стоит сделать для рабочей интеграции:
- 👤 Отдельный пользователь под интеграцию с минимальной ролью. Не используйте учётную запись администратора.
- 🔤 Латиница в логине. Кириллица в Basic-авторизации ломается на клиентах с другой кодировкой — надёжнее
api_trade. - 🔒 Только HTTPS. Basic передаёт пароль в обратимом виде. Без TLS его прочитает любой, кто видит трафик.
- ✅ Проверка прав в коде. Для чувствительных действий проверяйте
РольДоступна("ИмяРоли")и возвращайте 403.
Привилегированный режим
Иногда служебному пользователю не хватает прав на чтение регистра, а давать роль целиком не хочется. Тогда в обработчике точечно включают УстановитьПривилегированныйРежим(Истина) на время операции. Включайте его только после проверки входных данных, иначе любой клиент получит полный доступ к тому, что делает метод.
Анонимный доступ
Для приёма вебхуков от сторонних сервисов, которые не умеют Basic, пользователя прописывают в строке подключения публикации (default.vrd). Тогда авторизация 1С не спрашивается вообще. В таком режиме проверяйте секретный токен в заголовке запроса сами и закройте публикацию на веб-сервере по IP-адресам отправителя.
Производительность обработки запросов
Повторное использование сеансов
У HTTP-сервиса есть свойство Повторное использование сеансов. Без него на каждый запрос платформа открывает новый сеанс: авторизация, запуск модулей сеанса, захват лицензии. Это десятки и сотни миллисекунд на пустом месте.
| Значение | Как работает | Когда брать |
|---|---|---|
| Не использовать | Новый сеанс на каждый запрос | Редкие вызовы, отладка |
| Использовать | Клиент сам держит сеанс через cookie | Свой клиент, который умеет хранить cookie |
| Автоматически использовать | Платформа держит пул сеансов | Большинство интеграций |
Рядом задаётся Время жизни сеанса в секундах — сколько сеанс ждёт следующего запроса.
При повторном использовании сеанса значения, сохранённые в параметрах сеанса прошлым запросом, увидит следующий. Не храните там данные конкретного запроса.
Что ещё ускоряет ответ
- 📄 Пагинация. Списки отдавайте частями через
?limit=&page=, а не всю таблицу разом. Ставьте верхний предел — например, 500 строк. - 🔎 Запрос вместо обращения через точку. Выборка нужных полей одним запросом быстрее, чем
Заказ.Контрагент.ИННв цикле по строкам. - ⏳ Долгие операции в фоне. Пересчёт, загрузку тысяч строк, проведение пакета документов запускайте через
ФоновыеЗадания.Выполнить()и сразу отвечайте 202 с идентификатором задания. Статус клиент спросит отдельным GET. - 🧮 Короткие транзакции. Держите транзакцию только вокруг записи, без HTTP-вызовов наружу и без тяжёлых выборок внутри. Иначе запросы начнут ждать друг друга на блокировках.
Диагностика и логирование HTTP-запросов
Первый инструмент — curl. Он есть в Windows 10 и новее, в Windows Server 2019 и в любом Linux. Так вы отделяете проблемы сервиса от проблем клиента:
curl -i -u api_trade:Пароль ^
-H "Content-Type: application/json" ^
-d "{\"customer\":\"7701234567\"}" ^
http://srv01/trade/hs/api/orders
Ключ -i покажет код и заголовки ответа. В Linux вместо ^ в конце строк ставьте \.
Где искать следы
- 📒 Журнал регистрации. Сюда пишет ваш
ЗаписьЖурналаРегистрации. Отбирайте по имени события, напримерHTTPСервис.Заказы. - 🌐 Лог веб-сервера. Если запрос не дошёл до 1С (404 от Apache, 503), ответ — в access и error логах Apache или IIS.
- 🛠 Технологический журнал. Настраивается файлом
logcfg.xmlв каталогеconfплатформы. СобытиеEXCPпокажет исключения, которые не попали в ваш журнал. - 🐞 Отладка. В конфигураторе подключите отладку HTTP-сервисов: на клиенте и в публикации должна быть включена отладка. Точка останова в обработчике сработает при вызове из
curl.
Логируйте и успешные вызовы, но коротко: метод, адрес, код ответа, время. Тело пишите только для ошибок — иначе журнал разрастётся за неделю.
Ошибки, которые ломают HTTP-сервис в 1С
- ❌ Изменили шаблон — забыли обновить публикацию. Конфигурация обновлена, а веб-сервер работает со старым составом. Переопубликуйте базу.
- ❌ Чтение JSON в структуру. Падает на первом ключе с дефисом или цифрой в начале.
- ❌ Одна функция на все методы без проверки
HTTPМетод. Если на шаблон назначен общий метод*, сравнивайте метод сами, иначе DELETE выполнит код POST. - ❌ Сравнение строк без учёта регистра. Ключи
Соответствиеиз JSON чувствительны к регистру:Customerиcustomer— разные ключи. Договоритесь с клиентом о формате и проверяйте ровно его. - ❌ Даты без формата. Клиент шлёт
2026-10-07T10:00:00+03:00, а код ждётГГГГММДД. Для дат в JSON используйте функциюПрочитатьДатуJSONс подходящим форматом. - ❌ Обращение к клиентским методам. Модуль HTTP-сервиса выполняется на сервере:
Сообщить()и диалоги там бесполезны, всё выводится в ответ или журнал.
Частые вопросы
Можно ли получить тело в GET-запросе?
ПараметрыЗапроса.Как вернуть файл, например PDF счёта?
УстановитьТелоИзДвоичныхДанных. Добавьте заголовки Content-Type: application/pdf и Content-Disposition с именем файла.Почему браузерный JavaScript получает ошибку CORS?
Access-Control-Allow-Origin, Access-Control-Allow-Methods и Access-Control-Allow-Headers, и тот же Access-Control-Allow-Origin возвращайте в основных ответах.