В процессе интеграции 1С с внешними веб-сервисами (удобно через модуль обмена данными через HTTP-соединения) (будь то платежные шлюзы, ОФД или системы электронного документооборота) разработчики часто сталкиваются с ситуацией, когда запрос, успешно работающий в Postman, возвращает ошибку 404 Not Found при выполнении из кода 1С. Проанализируем причины этой проблемы и разберем правильный подход к написанию кода для взаимодействия с REST API по протоколу HTTP.
Основная и самая частая причина возникновения ошибки 404 в подобных сценариях — использование неверного метода запроса. В языке 1С:Предприятие объект HTTPСоединение имеет несколько методов для отправки данных, и каждый из них жестко соответствует определенному HTTP-глаголу.
Рассмотрим по шагам, что происходит в типичном ошибочном коде:
Ответ = Соединение.Получить(Запрос);
Метод Получить() всегда инициирует GET-запрос. Несмотря на то что вы можете предварительно установить тело запроса через Запрос.УстановитьТелоИзСтроки(), протокол HTTP и большинство веб-серверов ожидают, что GET-запросы не имеют тела. Если API сервиса (например, MicroPay) ожидает данные методом POST на конкретный адрес, а вы обращаетесь к нему методом GET, сервер может ответить кодом 404. Это происходит потому, что на сервере просто не настроен обработчик (роут) для метода GET по данному пути.
Для выполнения полноценного POST-запроса в 1С необходимо использовать метод ОтправитьДляОбработки() (поможет обработка для обмена данными через REST API). Перепишем фрагмент кода правильно:
// Вместо метода Получить(Запрос)
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Проанализируем структуру формирования запроса. Для корректной работы с 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
);
Если замена метода не помогла, выполним следующие шаги для поиска причины ошибки — пригодится инструмент пошаговой отладки кода в 1С:
Ресурс точно соответствует документации API. Символы /Transaction и /transaction для веб-сервера — это разные адреса./010101/Transaction/. Попробуйте оба варианта.ТекстОшибки = Ответ.ПолучитьТелоКакСтроку();.ЗащищенноеСоединениеOpenSSL с указанием допустимых протоколов.Объединим все вышеперечисленные рекомендации в один надежный блок кода:
АдресСервера = "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-сервисами.