Обмен данными между двумя базами 1С через HTTP-сервисы — это стандартная задача, которая, тем не менее, часто вызывает трудности у разработчиков. Особенно часто возникают вопросы с правильной адресацией, прохождением авторизации и извлечением переданных данных на стороне приемника. В этой статье мы подробно разберем, как отправить JSON из одной базы и корректно принять его в другой, избежав типичных ошибок вроде 403 Forbidden или пустых параметров запроса.
Рассмотрим ситуацию: вы настроили HTTPСоединение, указали логин и пароль, проверили ссылку в браузере или Postman — всё работает. Но при запуске кода из 1С сервер возвращает ошибку 403 (Доступ запрещен). Выясним причину этой ситуации.
Основная ошибка часто кроется в формировании объекта HTTPЗапрос. В 1С логика работы разделена: объект HTTPСоединение отвечает за физический адрес сервера и порт, а объект HTTPЗапрос — за конкретный путь к ресурсу (endpoint) внутри этого сервера.
Проанализируем некорректный подход:
// ОШИБКА: указание полного адреса в запросе
АдресРесурса = "http://localhost/my_base/hs/my_service/v1/load";
Запрос = Новый HTTPЗапрос(АдресРесурса);
Если в конструктор HTTPЗапрос передать строку, содержащую протокол и домен, веб-сервер (IIS или Apache) может некорректно интерпретировать запрос или вовсе отсечь его по соображениям безопасности, выдав 403. Правильный подход заключается в разделении адреса. Разберем по шагам:
HTTPСоединение указываем только имя сервера (хост) и порт.HTTPЗапрос указываем относительный путь, начиная от публикации базы.Пример правильного кода для отправки:
// Указываем только имя сервера
Сервер = "localhost";
Порт = 80;
Соединение = Новый HTTPСоединение(Сервер, Порт, "Логин", "Пароль");
// Указываем относительный путь к сервису БЕЗ протокола и домена
АдресРесурса = "/my_base/hs/cnt/cnt_load";
ЗаголовкиHTTP = Новый Соответствие;
ЗаголовкиHTTP.Вставить("Content-Type", "application/json");
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, ЗаголовкиHTTP);
HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаJSON);
Результат = Соединение.ВызватьHTTPМетод("POST", HTTPЗапрос);
Иногда даже при правильном разделении адреса 1С продолжает выдавать ошибку доступа. Рассмотрим альтернативный способ передачи учетных данных. В некоторых конфигурациях веб-серверов надежнее передать заголовок авторизации явно. Проанализируем, как это сделать:
// Формируем строку авторизации Basic вручную
ЛогинПароль = "Администратор:123";
ДанныеАвторизации = Base64Строка(ПолучитьДвоичныеДанныеИзСтроки(ЛогинПароль));
ЗаголовкиHTTP = Новый Соответствие;
ЗаголовкиHTTP.Вставить("Authorization", "Basic " + ДанныеАвторизации);
ЗаголовкиHTTP.Вставить("Content-Type", "application/json");
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, ЗаголовкиHTTP);
Важный момент: если вы используете IIS, убедитесь, что в настройках сайта включена "Анонимная проверка подлинности", чтобы 1С могла самостоятельно обработать заголовок Authorization.
Предположим, запрос ушел успешно, код состояния 200, но в базе-приемнике вы видите пустые ПараметрыURL и ПараметрыЗапроса. Посмотрим на ситуацию глазами обработчика HTTP-сервиса.
Многие начинающие разработчики ожидают увидеть данные JSON в коллекции ПараметрыЗапроса. Однако туда попадают только те данные, которые переданы в самой строке URL (после знака вопроса, например: ?id=123). Данные, которые мы поместили через УстановитьТелоИзСтроки, находятся в теле (Body) самого HTTP-пакета.
Чтобы извлечь их, в методе-обработчике (например, POST) необходимо использовать специальные методы объекта HTTPСервисЗапрос. Рассмотрим пример кода на стороне приемника:
Функция cnt_loadPOST(Запрос)
// Получаем тело запроса как обычную строку
СтрокаJSON = Запрос.ПолучитьТелоКакСтроку();
Если ПустаяСтрока(СтрокаJSON) Тогда
Ответ = Новый HTTPСервисОтвет(400); // Bad Request
Ответ.УстановитьТелоИзСтроки("Тело запроса пустое");
Возврат Ответ;
КонецЕсли;
// Преобразуем JSON в структуру 1С для дальнейшей работы
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);
Данные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
// Далее работаем с объектом 'Данные' (Массив или Структура)
// ... логика обработки ...
Ответ = Новый HTTPСервисОтвет(200);
Ответ.УстановитьТелоИзСтроки("Данные успешно приняты");
Возврат Ответ;
КонецФункции
Если вы передаете очень большие объемы JSON (например, выгрузку сотен тысяч контрагентов), метод ПолучитьТелоКакСтроку() может вызвать переполнение памяти, так как вся строка целиком загружается в ОЗУ. Проанализируем более профессиональный подход с использованием потоков.
Вместо чтения в строку, мы можем открыть поток чтения прямо из запроса. Это значительно ускорит работу и снизит нагрузку на сервер:
// Потоковое чтение JSON
Поток = Запрос.ПолучитьТелоКакПоток();
Чтение = Новый ЧтениеJSON;
Чтение.ОткрытьПоток(Поток);
// Сразу читаем данные в объекты 1С
Данные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
// Поток закроется автоматически вместе с объектом ЧтениеJSON
Если обмен всё равно не идет, воспользуйтесь следующими рекомендациями:
Попытка...Исключение. В блоке исключения записывайте ОписаниеОшибки() в журнал регистрации. Часто 1С "молчит" при ошибках парсинга JSON, и без логов причину не найти.Таким образом, успех обмена через HTTP-сервисы зависит от трех факторов: правильного разделения адреса между соединением и запросом, корректной передачи заголовков авторизации и понимания того, что данные JSON нужно извлекать из тела запроса, а не из его параметров.