При разработке интеграций в 1С часто возникает необходимость обмениваться данными с другими системами через HTTP-сервисы. В процессе отправки данных можно столкнуться с ошибкой 405 "Method Not Allowed". Давайте подробно разберем, почему она возникает и как ее исправить, на примере реальной ситуации, с которой столкнулся разработчик.
Основная проблема заключалась в отправке JSON-структуры на HTTP-сервис и получении в ответ кода состояния 405. При этом все адреса были верны, а сервис опубликован без ошибок.
Рассмотрим фрагмент кода, который приводил к ошибке. Задача — сформировать JSON-строку и отправить ее на сервер методом POST.
// ... код формирования СтрокаJSON ...
Сервер = "ones.unimatic.ru";
Попытка
Соединение = Новый HTTPСоединение(Сервер,, "ПользовательДляОбменов", "123");
Исключение
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = ОписаниеОшибки;
Сообщение.Сообщить;
Возврат;
КонецПопытки;
АдресРесурса = "/utmc_copy/hs/buhobmen/postschetnaoplatu/";
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "text/plain;charset=UTF-8");
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);
HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаJSON);
Попытка
// Первая отправка запроса на сервер
Соединение.ОтправитьДляОбработки(HTTPЗапрос);
// Вторая, ошибочная отправка запроса
Результат = Соединение.Получить(HTTPЗапрос);
Исключение
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = ОписаниеОшибки;
Сообщение.Сообщить;
Возврат;
КонецПопытки;
На первый взгляд, все кажется логичным: сначала отправляем данные, потом получаем результат. Но именно в этой логике и кроется ошибка. Проблема в непонимании того, как работают методы объекта HTTPСоединение в 1С.
Ошибка 405 "Method Not Allowed" означает, что метод, который вы используете для обращения к ресурсу (например, GET, POST, PUT), не разрешен для этого ресурса. В нашем случае сервер ожидал POST-запрос, а получил что-то другое, что и вызвало ошибку.
Чтобы понять причину ошибки, разберем ключевые методы, используемые в коде.
Соединение.ОтправитьДляОбработки(HTTPЗапрос): Этот метод предназначен для отправки запросов, у которых есть тело, то есть для методов POST или PUT. Важный момент: этот метод не просто отправляет данные, он также является функцией и возвращает результат — объект HTTPОтвет, содержащий код состояния, заголовки и тело ответа сервера.Соединение.Получить(HTTPЗапрос): Этот метод предназначен исключительно для отправки запросов методом GET. Он, как и предыдущий, отправляет запрос и возвращает HTTPОтвет. У GET-запросов, как правило, нет тела.Теперь вернемся к нашему коду. В нем выполняются два действия подряд:
Соединение.ОтправитьДляОбработки(HTTPЗапрос) — на сервер уходит корректный POST-запрос с телом JSON. Сервер его, скорее всего, успешно обрабатывает. Результат выполнения (объект HTTPОтвет) никуда не присваивается и теряется.Результат = Соединение.Получить(HTTPЗапрос) — сразу после этого на тот же самый адрес /utmc_copy/hs/buhobmen/postschetnaoplatu/ отправляется второй запрос, но уже методом GET. HTTP-сервис в конфигурации 1С был настроен так, что по этому адресу он ожидает только POST-запросы для получения и обработки данных. Когда он получает GET-запрос, он отвечает совершенно справедливо: "Метод не разрешен" (Error 405), так как обработчика для GET по этому URL у него нет.Таким образом, автор кода совершал две ошибки: отправлял два запроса вместо одного и использовал неподходящий метод для второго запроса.
Чтобы исправить код, нужно оставить только один вызов, который и отправляет данные, и получает ответ. Для POST-запроса это ОтправитьДляОбработки.
Это основной и самый правильный способ для отправки данных. Мы отправляем запрос и сразу присваиваем результат его выполнения переменной.
// ... код формирования HTTPЗапрос ...
HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаJSON);
Попытка
// Отправляем POST-запрос и СРАЗУ получаем ответ в переменную Результат
Результат = Соединение.ОтправитьДляОбработки(HTTPЗапрос);
// Теперь можно анализировать ответ сервера
Если Результат.КодСостояния = 200 Тогда
Сообщить("Данные успешно отправлены!");
// Читаем тело ответа, если нужно
ТелоОтвета = Результат.ПолучитьТелоКакСтроку();
Иначе
Сообщить("Ошибка на сервере. Код: " + Результат.КодСостояния);
Сообщить("Текст ошибки: " + Результат.ПолучитьТелоКакСтроку());
КонецЕсли;
Исключение
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = ОписаниеОшибки;
Сообщение.Сообщить;
Возврат;
КонецПопытки;
В этом варианте мы выполняем ровно одно действие: отправляем POST-запрос и получаем на него ответ. Никакой ошибки 405 больше не будет.
В платформе 1С есть еще один удобный метод — ВызватьHTTPМетод(). Он позволяет явно указать, какой HTTP-метод используется, что делает код более читаемым и гибким. Первый параметр — это строка с именем метода ("GET", "POST", "PUT" и т.д.).
// ... код формирования HTTPЗапрос ...
HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаJSON);
Попытка
// Явно указываем, что используем метод POST
Результат = Соединение.ВызватьHTTPМетод("POST", HTTPЗапрос);
// Дальнейшая обработка ответа аналогична первому решению
Если Результат.КодСостояния = 200 Тогда
Сообщить("Данные успешно отправлены!");
Иначе
Сообщить("Ошибка на сервере. Код: " + Результат.КодСостояния);
КонецЕсли;
Исключение
// ...
КонецПопытки;
Этот способ функционально эквивалентен первому для POST-запросов, но его использование может предотвратить путаницу, так как вы явно видите, какой метод вызывается.
Если вы столкнулись с ошибкой 405 и уверены, что используете правильный метод, проблема может быть глубже. Вот несколько шагов для отладки:
postschetnaoplatu_POST(...)).Главный вывод: всегда помните, что методы ОтправитьДляОбработки() и Получить() — это самодостаточные операции, которые и отправляют запрос, и возвращают ответ. Вызывать их в паре для одного и того же запроса — ошибка, которая часто приводит к путанице и проблемам, подобным ошибке 405.