Почему HTTP-сервис в 1С возвращает ошибку 404 при POST-запросе и как правильно настроить шаблоны URL?

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

При интеграции систем на платформе 1С:Предприятие 8 с внешними приложениями или при организации обмена между базами разработчики часто выбирают HTTP-сервисы. Это современный, легкий и быстрый механизм. Однако на этапе отладки многие сталкиваются с классической проблемой: запрос к сервису возвращает код состояния 404 Not Found. Особенно часто это происходит при отправке POST-запросов, в то время как GET-запросы по схожим адресам могут успешно работать.

В этой статье мы подробно разберем, почему возникает эта ошибка, как устроена маршрутизация запросов в 1С, и как правильно спроектировать HTTP-сервис для бесперебойной передачи данных в формате JSON.

Анализируем ситуацию: почему сервер возвращает 404?

Рассмотрим сценарий, с которым столкнулся автор темы. На стороне клиента выполняется следующий код для отправки POST-запроса:


Соединение = Новый HTTPСоединение("localhost", , "Admin", "1");

ЗаписьJSON = Новый ЗаписьJSON;    
ЗаписьJSON.УстановитьСтроку();

Структура = Новый Структура; 
Структура.Вставить("Поле1", "Значение1");    
Структура.Вставить("Поле2", "Значение2");
Структура.Вставить("Поле3", "Значение3");
ЗаписатьJSON(ЗаписьJSON, Структура);
        
СериализованнаяСтрока = ЗаписьJSON.Закрыть();
Запрос = Новый HTTPЗапрос("/BASE_KA_VNEDRENIE_RENAT/hs/Files");
Запрос.УстановитьТелоИзСтроки(СериализованнаяСтрока);

Результат = Соединение.ВызватьHTTPМетод("POST", Запрос);
Сообщить("Нам вернули код " + Результат.КодСостояния);

При попытке отправить этот запрос на адрес /BASE_KA_VNEDRENIE_RENAT/hs/Files система возвращает ошибку 404. При этом, если изменить адрес запроса на /BASE_KA_VNEDRENIE_RENAT/hs/Files/444, запрос успешно обрабатывается и возвращает код 200 OK.

Выясним причину такого поведения. Всё дело в настройке Шаблона URL в свойствах HTTP-сервиса внутри конфигуратора. Автор указал шаблон URL как /{File}. Для платформы 1С это означает следующее:

---

Пошаговое руководство: как правильно настроить шаблоны URL

Чтобы ваш HTTP-сервис корректно обрабатывал как запросы к коллекции ресурсов (например, создание нового файла через POST), так и запросы к конкретным элементам (получение файла по его идентификатору), необходимо спроектировать правильную структуру шаблонов URL. Рассмотрим, как это сделать по шагам.

Шаг 1. Разделение шаблонов в Конфигураторе

Внутри вашего HTTP-сервиса в ветке метаданных создайте два разных шаблона URL:

  1. Шаблон для работы со всей коллекцией (например, "ФайлыОбщий"):
    • Шаблон: / или /Files (в зависимости от корневого пути вашего сервиса).
    • Этот шаблон не содержит параметров в фигурных скобках.
    • Для этого шаблона создайте метод POST (для создания новых записей) и метод GET (для получения списка файлов).
  2. Шаблон для работы с конкретным элементом (например, "ФайлыДетально"):
    • Шаблон: /{File}.
    • Этот шаблон содержит обязательный параметр.
    • Для этого шаблона настройте методы GET (получить конкретный файл), PUT или POST (обновить данные), DELETE (удалить).

Благодаря такому разделению, запрос к /hs/Files будет перенаправлен на первый шаблон (создание ресурса), а запрос к /hs/Files/444 — на второй (работа с конкретным элементом).

---

Шаг 2. Реализация серверной части метода POST

Проанализируем, как должен выглядеть код обработчика POST-метода на стороне 1С. Нам нужно прочитать тело запроса, которое содержит сериализованную строку JSON, и преобразовать его обратно в структуру или соответствие 1С. Для этого лучше всего использовать чтение потока:


Функция ОбработатьФайлPOST(Запрос)
    
    Ответ = Новый HTTPСервисОтвет(200);
    
    // Получаем тело запроса в виде потока
    ПотокДанных = Запрос.ПолучитьТелоКакПоток();
    
    // Настраиваем чтение JSON
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.ОткрытьПоток(ПотокДанных);
    
    Попытка
        // Десериализуем JSON в структуру 1С
        Данные = ПрочитатьJSON(ЧтениеJSON);
        ЧтениеJSON.Закрыть();
        
        // Здесь выполняется бизнес-логика обработки полученных данных
        // Например, запись в справочник или регистр сведений
        ИмяФайла = Данные.Поле1; 
        
        // Формируем успешный ответ
        СтруктураОтвета = Новый Структура("Успешно", Истина);
        ЗаписьJSON = Новый ЗаписьJSON;
        ЗаписьJSON.УстановитьСтроку();
        ЗаписатьJSON(ЗаписьJSON, СтруктураОтвета);
        
        Ответ.УстановитьТелоИзСтроки(ЗаписьJSON.Закрыть(), КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
        Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
        
    Исключение
        // В случае ошибки парсинга возвращаем код 400 Bad Request
        Ответ.КодСостояния = 400;
        Ответ.УстановитьТелоИзСтроки("Ошибка обработки JSON: " + ОписаниеОшибки());
    КонецПопытки;
    
    Возврат Ответ;
    
КонецФункции

---

Шаг 3. Корректная настройка отправки HTTP-запроса на клиенте

При отправке данных в формате JSON на HTTP-сервис крайне важно правильно заполнять HTTP-заголовки запроса. По умолчанию веб-сервер или платформа 1С на принимающей стороне могут некорректно интерпретировать кодировку или тип содержимого, если они не указаны явно.

Рассмотрим доработанный и правильный вариант отправки POST-запроса:


// 1. Создаем соединение
Соединение = Новый HTTPСоединение("localhost", , "Admin", "1");

// 2. Сериализуем данные в JSON-строку
ЗаписьJSON = Новый ЗаписьJSON;    
ЗаписьJSON.УстановитьСтроку();
Структура = Новый Структура; 
Структура.Вставить("Поле1", "Значение1");    
Структура.Вставить("Поле2", "Значение2");
ЗаписатьJSON(ЗаписьJSON, Структура);
СериализованнаяСтрока = ЗаписьJSON.Закрыть();

// 3. Формируем заголовки запроса
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Заголовки.Вставить("Accept", "application/json");

// 4. Инициализируем запрос по правильному URL (без лишних параметров в конце)
Запрос = Новый HTTPЗапрос("/BASE_KA_VNEDRENIE_RENAT/hs/Files", Заголовки);

// 5. Устанавливаем тело запроса. Важно отключить BOM (Byte Order Mark),
// так как маркеры последовательности байтов могут ломать парсеры JSON на веб-серверах!
Запрос.УстановитьТелоИзСтроки(СериализованнаяСтрока, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

// 6. Отправляем запрос и получаем ответ
Результат = Соединение.ВызватьHTTPМетод("POST", Запрос);

Сообщить("Код состояния ответа: " + Результат.КодСостояния);
Сообщить("Тело ответа: " + Результат.ПолучитьТелоКакСтроку());

---

Важные нюансы публикации сервисов на IIS или Apache

Даже если ваш программный код написан абсолютно верно, а шаблоны настроены корректно, вы всё равно можете получать ошибку 404. Это связано с особенностями публикации баз 1С на веб-серверах. Обратите внимание на следующие моменты:

---

Дискуссия: Web-сервисы (SOAP) или HTTP-сервисы (REST)?

В сообщениях темы (в частности, в сообщении 9) прозвучало мнение, что для обменов между базами «1С-1С» лучше и проще использовать стандартные Web-сервисы (SOAP). Проанализируем это утверждение.

Преимущества Web-сервисов (SOAP) в 1С:

Преимущества HTTP-сервисов (REST) в 1С:

Поэтому, если планируется интеграция исключительно внутри закрытого контура "1С-1С", использование Web-сервисов действительно может сэкономить время разработчика. Однако во всех остальных случаях (интеграция с внешним миром, сайтами, мобильными клиентами) стандартом де-факто являются именно HTTP-сервисы с JSON.

← На главную