Как проверить соединение с базой 1С через OData и исправить ошибку 301

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Работа с внешними системами через стандартный интерфейс OData в 1С — это мощный инструмент интеграции, однако на этапе настройки разработчики часто сталкиваются с техническими препятствиями. Одной из самых распространенных проблем является получение кода состояния 301 Moved Permanently вместо ожидаемого ответа с данными. В этой статье мы подробно разберем, почему возникает эта ошибка, как правильно настроить параметры HTTPСоединение и как корректно передавать данные в базу, включая работу с табличными частями.

Разбор причины ошибки 301 (Moved Permanently)

Когда при выполнении запроса HTTPСоединение.Получить() или ОтправитьДляОбработки() сервер возвращает код 301, это означает, что ресурс был окончательно перемещен по другому адресу. Проанализируем ситуацию: сервер сообщает клиенту (вашему коду 1С), что запрос нужно повторить, но уже по другому URL. Рассмотрим основные причины, по которым это происходит в контексте 1С:

  1. Протокол HTTP вместо HTTPS. Если ваш веб-сервер (Apache или IIS) настроен на принудительное использование защищенного соединения, то при попытке обратиться по порту 80 вы получите перенаправление на порт 443.
  2. Отсутствие завершающего слеша. Веб-серверы часто настроены так, что обращения к каталогам без закрывающего знака / (например, .../standard.odata) перенаправляются на адрес со слешем (.../standard.odata/).
  3. Некорректное имя сервера. Использование localhost часто становится камнем преткновения.

Для диагностики первым делом нужно изучить заголовок Location, который приходит в ответе сервера. Разберем пример кода, который поможет увидеть, куда именно сервер пытается нас перенаправить:


Ответ = Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 301 Тогда
    НовыйАдрес = Ответ.Заголовки.Получить("Location");
    Сообщить("Сервер требует перенаправления на: " + НовыйАдрес);
КонецЕсли;

Важно помнить: объект HTTPСоединение в языке 1С автоматически не следует по пути из Location. Вам необходимо либо исправить исходный адрес в коде, либо программно обработать редирект.

Проблема "localhost" и контекст выполнения кода

Проанализируем ситуацию, описанную в сообщениях форума: почему обращение к localhost часто приводит к ошибке? Здесь важно понимать разницу между клиентским и серверным контекстом 1С.

Выясним причину: когда вы пишете Сервер = "localhost", это обращение к "самому себе". Если код выполняется &НаКлиенте, 1С ищет веб-сервер на компьютере пользователя. Если код выполняется &НаСервере, 1С ищет веб-сервер на той машине, где установлена серверная часть (кластер) 1С.

Если ваша база опубликована на отдельном веб-сервере, отличном от того, где запущен кластер 1С, использование localhost в серверном коде будет ошибкой. Вместо этого необходимо указывать реальный IP-адрес или сетевое имя сервера, на котором произведена публикация. Рассмотрим правильный вариант инициализации соединения:


ПараметрыСоединения = Новый Структура;
// Указываем реальное имя сервера в сети, а не localhost
ПараметрыСоединения.Вставить("Сервер", "192.168.1.10"); 
ПараметрыСоединения.Вставить("Порт", 80);
ПараметрыСоединения.Вставить("Пользователь", "ODataUser");
ПараметрыСоединения.Вставить("Пароль", "StrongPassword123");

ЗащищенноеСоединение = Неопределено; // Используйте Новый ЗащищенноеСоединениеOpenSSL(), если нужен HTTPS
HTTPСоединение = Новый HTTPСоединение(
    ПараметрыСоединения.Сервер, 
    ПараметрыСоединения.Порт, 
    ПараметрыСоединения.Пользователь, 
    ПараметрыСоединения.Пароль, 
    , , 
    ЗащищенноеСоединение
);

Запись данных через метод POST

Рассмотрим подробнее, как передавать данные для создания новых объектов в базе через OData. Для этого используется метод POST, а данные передаются в теле запроса в формате JSON. Посмотрим на структуру формирования данных для одного документа:


ДанныеДокумента = Новый Соответствие;
// GUID должен быть в формате строки: "00000000-0000-0000-0000-000000000000"
ДанныеДокумента.Вставить("Организация_Key", "d4aff59d-d3a8-11ed-8dfa-10bf48ba43bd");
// Дата передается строго в формате ISO: YYYY-MM-DDTHH:mm:ss
ДанныеДокумента.Вставить("Date", Формат(ТекущаяДатаСеанса(), "ДФ=yyyy-MM-ddTHH:mm:ss"));
ДанныеДокумента.Вставить("Comment", "Создано через OData");

// Преобразование в JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеДокумента);
СтрокаЗапроса = ЗаписьJSON.Закрыть();

АдресРесурса = "/buh_dev/odata/standard.odata/Document_РеализацияТоваровУслуг";
Запрос = Новый HTTPЗапрос(АдресРесурса);
Запрос.УстановитьТелоИзСтроки(СтрокаЗапроса);
Ответ = HTTPСоединение.ОтправитьДляОбработки(Запрос);

Как передать табличную часть документа

Часто возникает вопрос: как за один запрос передать не только реквизиты шапки, но и строки табличной части? Разберем по шагам этот процесс. В OData 1С табличная часть представляется как массив объектов (структур или соответствий), вложенный в основной объект данных под именем этой табличной части.

Проанализируем пример формирования данных для документа с табличной частью Товары:


ДанныеОбъекта = Новый Соответствие;
ДанныеОбъекта.Вставить("Организация_Key", "GUID-организации");

// Создаем массив для хранения строк табличной части
МассивСтрокТЧ = Новый Массив;

// Формируем первую строку
СтрокаТЧ = Новый Соответствие;
СтрокаТЧ.Вставить("LineNumber", "1");
СтрокаТЧ.Вставить("Номенклатура_Key", "GUID-номенклатуры");
СтрокаТЧ.Вставить("Количество", 10);
СтрокаТЧ.Вставить("Цена", 1500);
МассивСтрокТЧ.Добавить(СтрокаТЧ);

// Добавляем массив строк в основной объект по имени ТЧ
ДанныеОбъекта.Вставить("Товары", МассивСтрокТЧ);

// Сериализуем в JSON и отправляем POST-запрос, как в примере выше

Важный момент: если вы используете метод PATCH для обновления существующего документа, передача табличной части в запросе обычно полностью заменяет (перезаписывает) все существующие строки в базе данными из вашего запроса. Будьте осторожны, чтобы не удалить существующие данные по ошибке.

Пакетная запись данных ($batch)

Хотя стандартные примеры показывают создание одного объекта за раз, OData поддерживает механизм $batch. Это позволяет объединить несколько операций (создание, изменение) в один HTTP-запрос. Это критически важно для производительности, так как накладные расходы на установку HTTP-соединения часто превышают время самой записи данных.

Режим $batch требует формирования сложного тела запроса в формате multipart/mixed. Если вам нужно передать тысячи объектов, стоит изучить этот механизм подробнее в документации к платформе 1С.

Настройка публикации и доступа

Если соединение все равно не устанавливается, проверим настройки самой публикации базы:

Используя эти рекомендации, вы сможете эффективно настроить взаимодействие с 1С через интерфейс OData, корректно обрабатывая ошибки соединения и правильно структурируя передаваемые данные.

← На главную