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

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

В процессе интеграции 1С с внешними веб-сервисами (удобно через модуль обмена данными через HTTP-соединения) (будь то платежные шлюзы, ОФД или системы электронного документооборота) разработчики часто сталкиваются с ситуацией, когда запрос, успешно работающий в Postman, возвращает ошибку 404 Not Found при выполнении из кода 1С. Проанализируем причины этой проблемы и разберем правильный подход к написанию кода для взаимодействия с REST API по протоколу HTTP.

Различие методов GET и POST в платформе 1С

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

Рассмотрим по шагам, что происходит в типичном ошибочном коде:

Ответ = Соединение.Получить(Запрос);

Метод Получить() всегда инициирует GET-запрос. Несмотря на то что вы можете предварительно установить тело запроса через Запрос.УстановитьТелоИзСтроки(), протокол HTTP и большинство веб-серверов ожидают, что GET-запросы не имеют тела. Если API сервиса (например, MicroPay) ожидает данные методом POST на конкретный адрес, а вы обращаетесь к нему методом GET, сервер может ответить кодом 404. Это происходит потому, что на сервере просто не настроен обработчик (роут) для метода GET по данному пути.

Для выполнения полноценного POST-запроса в 1С необходимо использовать метод ОтправитьДляОбработки() (поможет обработка для обмена данными через REST API). Перепишем фрагмент кода правильно:


// Вместо метода Получить(Запрос)
Ответ = Соединение.ОтправитьДляОбработки(Запрос);

Настройка HTTP-запроса и авторизации

Проанализируем структуру формирования запроса. Для корректной работы с API часто требуется передача заголовков авторизации и типа контента. Разберем пример формирования заголовка Basic Authentication и подготовку JSON-тела. Для этой задачи есть консоль кода и запросов для тестирования алгоритмов.

Посмотрим на пример формирования заголовков:


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

// Формируем строку авторизации
СтрокаАвторизации = ПолучитьBase64СтрокуИзДвоичныхДанных(
    ПолучитьДвоичныеДанныеИзСтроки(ИмяПользователя + ":" + Пароль, КодировкаТекста.UTF8, Ложь)
);
Заголовки.Вставить("Authorization", "Basic " + СтрокаАвторизации); 

Запрос = Новый HTTPЗапрос(Ресурс, Заголовки);
Запрос.УстановитьТелоИзСтроки(СтрокаJS, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

Важный нюанс: при использовании метода УстановитьТелоИзСтроки() рекомендуется явно указывать третий параметр ИспользованиеByteOrderMark.НеИспользовать. Некоторые веб-серверы некорректно воспринимают наличие BOM-символов в начале JSON-строки и могут вернуть ошибку парсинга или 404, так как структура данных кажется им нарушенной.

Влияние прокси-сервера на запросы

Если при анализе трафика через отладчик (например, Fiddler) вы обнаруживаете лишние заголовки, такие как Proxy-Authorization: NTLM, это означает, что 1С пытается выполнить запрос через системные настройки прокси вашего компьютера или сервера — в этом поможет инструмент анализа HTTP-запросов и ответов. В корпоративных сетях это может приводить к искажению запроса или блокировке его прокси-сервером.

Чтобы гарантированно исключить влияние системного прокси, инициализируйте соединение с пустым объектом прокси. Рассмотрим, как это сделать:


// Параметр Ложь в конструкторе ИнтернетПрокси отключает использование системных настроек
SSL = Новый ЗащищенноеСоединениеOpenSSL;
Прокси = Новый ИнтернетПрокси(Ложь);

Соединение = Новый HTTPСоединение(
    АдресСервера,
    2158, // Порт
    ,     // Логин (если используется встроенная в 1С авторизация)
    ,     // Пароль
    Прокси,
    ,     // Таймаут
    SSL
);

Пошаговый алгоритм отладки HTTP-соединения

Если замена метода не помогла, выполним следующие шаги для поиска причины ошибки — пригодится инструмент пошаговой отладки кода в 1С:

  1. Проверка регистра URL: Убедитесь, что переменная Ресурс точно соответствует документации API. Символы /Transaction и /transaction для веб-сервера — это разные адреса.
  2. Слеш в конце адреса: Иногда сервер ожидает завершающий слеш, например /010101/Transaction/. Попробуйте оба варианта.
  3. Анализ тела ответа: Даже при ошибке 404 сервер часто возвращает JSON с подробным описанием проблемы. Обязательно считывайте тело ответа даже при неудачном коде состояния: ТекстОшибки = Ответ.ПолучитьТелоКакСтроку();.
  4. Проверка порта: Если сервис использует нестандартный порт (например, 2158), убедитесь, что он открыт в вашем брандмауэре для исходящих соединений со стороны сервера 1С.
  5. Версия TLS: Современные сервисы требуют протокол TLS 1.2. В старых версиях Windows или при использовании устаревших компонент 1С может потребоваться явная настройка ЗащищенноеСоединениеOpenSSL с указанием допустимых протоколов.

Итоговый пример корректного POST-запроса

Объединим все вышеперечисленные рекомендации в один надежный блок кода:


АдресСервера = "micropay.e-ofd.ru";
Ресурс = "/0101010101010101/Transaction";
SSL = Новый ЗащищенноеСоединениеOpenSSL();
Прокси = Новый ИнтернетПрокси(Ложь); // Отключаем лишние прокси-заголовки

Соединение = Новый HTTPСоединение(АдресСервера, 2158, , , Прокси, 30, SSL);

Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
// Ручное формирование Basic Auth
AuthData = ПолучитьBase64СтрокуИзДвоичныхДанных(ПолучитьДвоичныеДанныеИзСтроки("User:Pass", КодировкаТекста.UTF8, Ложь));
Заголовки.Вставить("Authorization", "Basic " + AuthData);

Запрос = Новый HTTPЗапрос(Ресурс, Заголовки);
Запрос.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

Попытка
    // Используем ОтправитьДляОбработки для POST запроса
    Ответ = Соединение.ОтправитьДляОбработки(Запрос);
    Если Ответ.КодСостояния = 200 Тогда
        Сообщить("Успешно: " + Ответ.ПолучитьТелоКакСтроку());
    Иначе
        Сообщить("Ошибка " + Ответ.КодСостояния + ": " + Ответ.ПолучитьТелоКакСтроку());
    КонецЕсли;
Исключение
    Сообщить("Ошибка связи: " + ОписаниеОшибки());
КонецПопытки;

Использование правильного метода ОтправитьДляОбработки() в сочетании с контролем прокси-настроек и корректной кодировкой тела запроса позволяет избежать большинства ошибок при интеграции 1С с внешними REST-сервисами.

← На главную