При разработке интеграционных решений на платформе 1С, используя HTTP-сервисы, мы часто сталкиваемся с необходимостью обрабатывать различные типы HTTP-запросов, включая GET и POST — для решения таких задач есть REST API для работы с документами 1С.. В ситуации, когда GET-запросы успешно выполняются, а POST-запросы возвращают ошибку 405 ('Method Not Allowed' – метод не разрешен), это указывает на то, что веб-сервер или сам HTTP-сервис 1С не разрешает использование метода POST для запрашиваемого ресурса. Давайте подробно разберем, почему возникает эта ошибка и как мы можем ее устранить.
Ошибка 405 — это стандартный код состояния HTTP, который означает, что метод, указанный в запросе (в нашем случае POST), не поддерживается для запрошенного ресурса на сервере. Это отличается от ошибки 404 ('Not Found'), которая означает, что сам ресурс не найден. В случае 405, ресурс найден, но он не настроен для обработки такого типа запроса.
Если ваши GET-запросы работают корректно, это уже хороший знак, поскольку он подтверждает базовую работоспособность HTTP-сервиса и доступность веб-сервера — организовать такой обмен поможет обмен данными через веб-сервис для 1С.. Проблема, скорее всего, кроется в конкретной настройке обработчика для POST-запросов.
Первоочередная и самая частая причина ошибки 405 при работе с HTTP-сервисами 1С заключается в некорректной или отсутствующей настройке метода POST непосредственно в конфигурации 1С.
Для этого откроем конфигурацию, перейдем к ветке "HTTP-сервисы", выберем наш HTTP-сервис, затем его шаблон URL и в нем — методы. Убедитесь, что там присутствует метод с именем, например, ПринятьДанные, и его тип HTTP-запроса установлен как POST.
/MyService/api/data, убедитесь, что именно такой шаблон или соответствующий ему шаблон с параметрами (например, /MyService/api/{Параметр}/data) определен в конфигурации.POST-запросы, в отличие от GET, обычно передают данные в теле запроса. Ошибки в формировании тела запроса или заголовков могут косвенно приводить к проблемам, хотя 405 ошибка чаще указывает на проблему с самим методом. Тем не менее, давайте рассмотрим потенциальные проблемы:
Content-Type. Например, если вы передаете данные в формате JSON, заголовок должен быть application/json. Для XML-данных это будет application/xml, а для форм — application/x-www-form-urlencoded или multipart/form-data. Неправильный Content-Type может помешать серверу корректно распарсить тело запроса.Запрос.ПолучитьТелоКакСтроку() для получения строкового представления тела запроса. Если данные передаются в бинарном виде, то Запрос.ПолучитьТелоКакДвоичныеДанные(). Далее мы должны убедиться, что наш код правильно обрабатывает полученную строку, например, десериализует JSON с помощью ПрочитатьJSON().Вот пример простого обработчика HTTP-сервиса для POST-запроса:
// Пример обработчика для метода POST в HTTP-сервисе 1С
Функция PostПримерМетода(Запрос)
Ответ = Новый HTTPСервисОтвет(200); // По умолчанию считаем, что все ОК
Ответ.УстановитьЗаголовок("Content-Type", "application/json; charset=utf-8");
Попытка
ТелоЗапросаСтрокой = Запрос.ПолучитьТелоКакСтроку();
// Отладочная информация: записываем тело запроса в журнал регистрации
// Если ТелоЗапросаСтрокой <> Неопределено Тогда
// ЗаписьЖурналаРегистрации(
// "HTTPСервис.PostПримерМетода",
// УровеньЖурналаРегистрации.Информация,
// ,
// ,
// "Тело запроса: " + ТелоЗапросаСтрокой
// );
// КонецЕсли;
// Пример десериализации JSON
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ТелоЗапросаСтрокой);
ДанныеЗапроса = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
// Здесь мы обрабатываем полученные ДанныеЗапроса
// Например, создаем новый объект или обновляем существующий
// ...
// Формируем ответ
РезультатОтвет = Новый Соответствие;
РезультатОтвет.Вставить("Статус", "Успех");
РезультатОтвет.Вставить("Сообщение", "Данные успешно получены и обработаны.");
// Добавим полученные данные в ответ для наглядности (необязательно в реальном коде)
РезультатОтвет.Вставить("ПолученныеДанные", ДанныеЗапроса);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку(Новый Строка);
ЗаписьJSON.ЗаписатьНачалоОбъекта();
Для Каждого КлючЗначение Из РезультатОтвет Цикл
ЗаписьJSON.ЗаписатьИмяСвойства(КлючЗначение.Ключ);
ЗаписьJSON.ЗаписатьЗначение(КлючЗначение.Значение);
КонецЦикла;
ЗаписьJSON.ЗаписатьКонецОбъекта();
СтрокаОтвета = ЗаписьJSON.Закрыть();
Ответ.УстановитьТелоИзСтроки(СтрокаОтвета);
Исключение
// В случае ошибки формируем ответ с кодом 500
Ответ.КодСостояния = 500;
РезультатОтвет = Новый Соответствие;
РезультатОтвет.Вставить("Статус", "Ошибка");
РезультатОтвет.Вставить("Сообщение", "Ошибка обработки запроса: " + ОписаниеОшибки());
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку(Новый Строка);
ЗаписьJSON.ЗаписатьНачалоОбъекта();
Для Каждого КлючЗначение Из РезультатОтвет Цикл
ЗаписьJSON.ЗаписатьИмяСвойства(КлючЗначение.Ключ);
ЗаписьJSON.ЗаписатьЗначение(КлючЗначение.Значение);
КонецЦикла;
ЗаписьJSON.ЗаписатьКонецОбъекта();
СтрокаОтвета = ЗаписьJSON.Закрыть();
Ответ.УстановитьТелоИзСтроки(СтрокаОтвета);
КонецПопытки;
Возврат Ответ;
КонецФункции
Хотя в нашем случае проблема возникла при проверке HTTP-сервиса ИЗ Postman, стоит упомянуть другую распространенную причину ошибки 405, когда мы сами отправляем POST-запросы ИЗ 1С.
Если вы пишете код в 1С для отправки POST-запроса на внешний ресурс и получаете ошибку 405, это может быть связано с использованием неправильного метода объекта HTTPСоединение. Мы должны помнить, что для отправки POST-запросов следует использовать методы Соединение.ОтправитьДляОбработки(HTTPЗапрос) или Соединение.Отправить(HTTPЗапрос), а не Соединение.Получить(HTTPЗапрос), который предназначен исключительно для GET-запросов. Если по ошибке мы пытаемся передать тело запроса через Соединение.Получить(), сервер не сможет его обработать и может вернуть 405.
Давайте рассмотрим пример правильной отправки POST-запроса из 1С:
// Пример отправки POST-запроса из клиентского кода 1С
Функция ОтправитьPOSTЗапросИз1С(URLСервиса, ТелоЗапросаJSON) Экспорт
Соединение = Новый HTTPСоединение("example.com", , , , , , Истина, 15); // Замените example.com на домен вашего сервера
// Формируем HTTPЗапрос
Запрос = Новый HTTPЗапрос(URLСервиса); // Например, "/MyService/api/data"
Запрос.УстановитьЗаголовок("Content-Type", "application/json; charset=utf-8");
Запрос.УстановитьТелоИзСтроки(ТелоЗапросаJSON, КодировкаТекста.UTF8);
Попытка
// Правильный метод для отправки POST-запроса
Ответ = Соединение.ОтправитьДляОбработки(Запрос); // или Соединение.Отправить(Запрос)
Если Ответ.КодСостояния = 200 Тогда
Возврат Ответ.ПолучитьТелоКакСтроку();
Иначе
Сообщить("Ошибка HTTP-запроса. Код состояния: " + Ответ.КодСостояния + ". " + Ответ.ПолучитьТелоКакСтроку());
Возврат Неопределено;
КонецЕсли;
Исключение
Сообщить("Произошла ошибка при отправке POST-запроса: " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
КонецФункции
// Пример вызова
// JsonДляОтправки = "{""Ключ"": ""Значение"", ""Число"": 123}";
// Результат = ОтправитьPOSTЗапросИз1С("/path/to/my/api", JsonДляОтправки);
// Если Результат <> Неопределено Тогда
// Сообщить("Успешно получен ответ: " + Результат);
// КонецЕсли;
Иногда ошибка 405 может быть вызвана ограничениями на уровне веб-сервера, на котором опубликована база 1С. Мы должны проверить конфигурацию веб-сервера:
.htaccess для Apache или nginx.conf для Nginx) на наличие правил, которые могут запрещать POST-запросы для определенных директорий или страниц (например, директивы Limit Except POST в Apache или deny method POST в Nginx).Для эффективного поиска причины ошибки мы рекомендуем использовать комплексный подход к отладке — для этого есть инструменты для отладки и анализа кода 1С::
Access-Control-Allow-Origin, Access-Control-Allow-Methods и Access-Control-Allow-Headers в ответе.Для систематического устранения ошибки 405 при работе с POST-запросами мы рекомендуем следующий подход:
{} или простейшей строкой) с корректным Content-Type. Это поможет исключить ошибки в теле запроса.Следуя этим шагам, мы сможем эффективно локализовать и устранить причину ошибки 405, обеспечив стабильную работу наших HTTP-сервисов в 1С.