Отправка PUT запроса средствами 1С 8.3

16.02.17

Разработка - Запросы

HTTP запрос с использованием метода PUT средствами 1С 8.3 на практике - проблема и решение

При разработке процедуры отправки на сайт информации из 1С с версией платформы 8.3.9.2170 столкнулся с проблемой: разработчик сайта предоставил мне возможность записывать нужную информацию только при помощи HTTP запроса методом PUT.

Недолго думая, я набросал простенький код:
    Соединение = Новый HTTPСоединение("www.mysite.ru");
    Заголовки = Новый Соответствие;
    Заголовки["Content-Type"] = "application/x-www-form-urlencoded";
    Запрос = Новый HTTPЗапрос("/api/order_items/93076?order_item[qnt_income]=30", Заголовки);
    Соединение.Записать(Запрос);

По результатам выполнения в соответствующей строке заказа покупателя на сайте должно было проставиться количество поступившего на склад товара.

Однако, как вы уже наверно поняли, ничего не произошло. После того как я убедился, что на сайте ошибок нет  (путем отправки аналогичного запроса через плагин к Хрому), я запустил на своем локальном компьютере web-сервер и стал экспериментировать.
Сразу же выяснилась странная вещь: вышеприведенный код генерирует не PUT, а HEAD запрос!
В логах апача я увидел следующее:
127.0.0.1 - - [16/Feb/2017:14:38:54 +0400] "HEAD /api/order_items/93076?order_item[qnt_income]=30 HTTP/1.1"
Я немного удивился (в руководстве ведь было черным по белому написано PUT), но не растерялся - можно ведь вызвать метод напрямую:
Соединение.ВызватьHTTPМетод("PUT",Запрос);
В логах то же самое:
127.0.0.1 - - [16/Feb/2017:14:40:52 +0400] "HEAD /api/order_items/93076?order_item[qnt_income]=30 HTTP/1.1"
"Может быть я что-то не так делаю?" - задал я себе вопрос. Но в интернете и в мануалах не было никаких подсказок. Что ж, метод научного тыка еще никто не отменял. Для начала я попробовал сделать так: 
Соединение.ВызватьHTTPМетод("фывфыв",Запрос);
В логах получил:
127.0.0.1 - - [16/Feb/2017:14:53:03 +0400] "?????? /api/order_items/93076?order_item[qnt_income]=30 HTTP/1.1"

Любопытно, значит 1С заменяет конкретно метод PUT (чем же он 1С не угодил?).

После еще нескольких попыток я пришел к варианту: 
Соединение.ВызватьHTTPМетод("PUT ",Запрос);
В логах получил:
127.0.0.1 - - [16/Feb/2017:14:53:03 +0400] "PUT  /api/order_items/93076?order_item[qnt_income]=30 HTTP/1.1"

И уже этот вариант отработал на сайте и все остались довольны.

UPD.

Алексей 1 (AlX0id)  подсказал более корректное решение проблемы: необходимо задать тело запроса, любое, даже пустое. Например, сработает такой вариант:
    Соединение = Новый HTTPСоединение("www.mysite.ru");
    Заголовки = Новый Соответствие;
    Заголовки["Content-Type"] = "application/x-www-form-urlencoded";
    Запрос = Новый HTTPЗапрос("/api/order_items/93076?order_item[qnt_income]=30", Заголовки);
    Запрос.УстановитьТелоИзСтроки("", КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать); 
    Соединение.Записать(Запрос);

И уже совсем правильно, наверное, передавать в теле запроса сами значения параметров.

Вывод следующий: PUT запрос без тела платформа 1С считает ошибочным и заменяет метод на HEAD.
Любопытно что POST запрос без тела 1С никак не отслеживает и не превращает в GET, проверял ради спортивного интереса.
Как сказал бы всем известный Вовочка из знаменитого анекдота: "Где логика?".

Надеюсь кому-то моя публикация сбережет несколько часов жизни в поисках ответа. =)))

HTTP запрос PUT ошибки 1С

См. также

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

13000 руб.

02.09.2020    119922    656    389    

701

Для чего используют конструкцию запроса "ГДЕ ЛОЖЬ" в СКД на примере конфигурации 1С:ERP

Запросы СКД Платформа 1С v8.3 Запросы Система компоновки данных 1С:ERP Управление предприятием 2 Бесплатно (free)

В типовых конфигурациях разработчики компании 1С иногда используют в отчетах, построенных на СКД, такую конструкцию, как "ГДЕ ЛОЖЬ". Такая конструкция говорит о том, что данные в запросе не будут получены совсем. Для чего же нужен тогда запрос?

13.02.2024    5620    KawaNoNeko    23    

23

Набор-объект для СКД по тексту или запросу

Запросы СКД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    1964    2    Yashazz    0    

29

Запрос 1С copilot

Инструментарий разработчика Запросы Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Пишем на человеческом языке, что нам надо, и получаем текст запроса на языке 1С. Используются большие языковые модели (LLM GPT) от OpenAI или Яндекс на выбор.

5 стартмани

15.01.2024    6091    29    mkalimulin    23    

48

PrintWizard: поддержка представлений ЗУП в конструкторе

Инструментарий разработчика Запросы Платформа 1С v8.3 Бесплатно (free)

Одной из интересных задач, стоящих в процессе разработки, была поддержка механизма представлений в ЗУП. Но не просто возможность исполнения запросов с ними. Основная проблема была в том, чтобы с ними было удобно работать, а именно: создавать, модифицировать и отлаживать. Кратко о том, что в итоге получилось...

14.12.2023    1714    vandalsvq    7    

28

Объектная модель запроса "Схема запроса" 2

Запросы Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

Далеко уже не новый тип данных "Схема запроса". Статья о том, как использовать его "попроще". Примеры создания текста запроса с нуля и изменение имеющегося запроса.

06.12.2023    5283    user1923546    26    

43

Начните уже использовать хранилище запросов

HighLoad оптимизация Запросы

Очень немногие из тех, кто занимается поддержкой MS SQL, работают с хранилищем запросов. А ведь хранилище запросов – это очень удобный, мощный и, главное, бесплатный инструмент, позволяющий быстро найти и локализовать проблему производительности и потребления ресурсов запросами. В статье расскажем о том, как использовать хранилище запросов в MS SQL и какие плюсы и минусы у него есть.

11.10.2023    15957    skovpin_sa    14    

98
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Ликреонский 238 17.02.17 08:11 Сейчас в теме
Странно:
Соединение.ВызватьHTTPМетод("PUT",Запрос);
Соединение.ВызватьHTTPМетод("PUT ",Запрос);

Разница в один пробел и в этом все дело?
2. hspeed79 94 17.02.17 09:26 Сейчас в теме
(1) да, удивительно, но факт =)
3. Ликреонский 238 17.02.17 10:10 Сейчас в теме
(2)Чудны дела твои, Нуралиев :)
user1485967; simonovich; Aparatus; bulpi; +4 1 Ответить
4. pbazeliuk 1954 17.02.17 10:49 Сейчас в теме
Спасибо, полезная информация.
5. frkbvfnjh 785 17.02.17 15:36 Сейчас в теме
Вам бы на форуме специалистов поднять это вопрос. Возможно это как всегда ошибка в платформе. Вы наверное первый кто воспользовался PUT в 1С. Есть чувство что сами разработчики даже проверять не стали...
Chizhik2020; EMelihoff; +2 Ответить
6. AlX0id 17.02.17 16:17 Сейчас в теме
(5)
ЗапросКСайту = Новый HTTPЗапрос(ТекстЗапроса,ЗаголовокЗапроса(Заголовки));
	
	Если Тело <> Неопределено Тогда
		ЗапросКСайту.УстановитьТелоИзСтроки(Тело, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать); 
	КонецЕсли;
	
Результат = Соединение.ВызватьHTTPМетод("PUT", ЗапросКСайту, РезультатИмяФайла);


Так работало еще с полгода назад.
Nikitos_NSK; Yimaida; +2 Ответить
7. starik-2005 3031 17.02.17 16:42 Сейчас в теме
(6) все зависит от того, как работает. Если на стороне сайта нет разницы, пут пришел или хид, то и так сработает. Если с файлом генерится пут, то, видимо, какая-то мистика в 1С.
dj_serega; +1 Ответить
8. dj_serega 390 17.02.17 17:25 Сейчас в теме
(7)
на стороне сайта нет разницы

Я бы хотел уточнить. Может на стороне вебсервера сайта? :)
9. AlX0id 17.02.17 18:51 Сейчас в теме
(7)
Полез проверять.. Думаю, вроде фиддлером все проверял, и в документации был именно PUT..
&НаКлиенте
Процедура Команда2(Команда)
	
	Тело = "фывафыва";
	Соединение = Новый HTTPСоединение("mysite.tk");
    Заголовки = Новый Соответствие;
    Заголовки["Content-Type"] = "application/x-www-form-urlencoded";
	Запрос = Новый HTTPЗапрос("/api/order_items/93076?order_item[qnt_income]=30", Заголовки);
	Запрос.УстановитьТелоИзСтроки(Тело, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать); 
	Соединение.ВызватьHTTPМетод("PUT",Запрос);
	
КонецПроцедуры

&НаКлиенте
Процедура Команда3(Команда)
	
	Тело = "фывафыва";
	Соединение = Новый HTTPСоединение("mysite.tk");
    Заголовки = Новый Соответствие;
    Заголовки["Content-Type"] = "application/x-www-form-urlencoded";
	Запрос = Новый HTTPЗапрос("/api/order_items/93076?order_item[qnt_income]=30", Заголовки);
	Соединение.ВызватьHTTPМетод("PUT",Запрос);
	
КонецПроцедуры
Показать


Вот Команда2 - дает PUT. А Команда3 - уже HEAD. Так что, видимо, дело-то не в пробеле, а в отсутствии тела как такового..
insurgut; Gendelf; COMPER; vld_dmn; websamson; morin; json; Yimaida; +8 Ответить
10. hspeed79 94 17.02.17 19:40 Сейчас в теме
(9) Понятно, добрая 1С не дает нам ошибиться и отеческой рукой меняет метод за нас.
Спасибо за подсказку, все таки у меня изначально был некорректный скрипт.
insurgut; +1 Ответить
11. vitaliy1911 38 20.02.17 09:32 Сейчас в теме
да, сталкивался с этой проблемой. довольно странное поведение. вот тут поднимал эту тему http://www.forum.mista.ru/topic.php?id=784496
13. Evil Beaver 8100 12.03.17 08:40 Сейчас в теме
Ваабче-то, метод PUT (как и POST) предполагает наличие тела, т.е. именно того, что вы будете "Помещать" и "Постить". Без тела эти методы смысла не имеют. Другой вопрос, имеет ли право 1С подменять метод, если не видит тело. На мой взгляд, тут должно быть исключение, а не неочевидная замена на HEAD. Но в любом случае, без "тела" эти методы не должны применяться.
WinterIT; Merkalov; Irwin; Drivingblind; vld_dmn; ness; +6 Ответить
14. ness 09.08.18 18:23 Сейчас в теме
Было полезно, спасибо.
15. dsdred 3231 20.08.18 23:09 Сейчас в теме
http-сервис поднял на 8.3.10.2650 + IIS 6, обращался из 8.3.12.1595, ошибку не словил. Наверное исправили...
Использовал метод Любой(ANY)
Функция PAPI_ALL(Запрос)
	Ответ = Новый HTTPСервисОтвет(200);
	Результат = "";
	Результат = Результат + Запрос.HTTPМетод + Символы.ПС;
	Результат = Результат + Запрос.БазовыйURL + Символы.ПС;
	Результат = Результат + Запрос.ОтносительныйURL + Символы.ПС + Символы.ПС;
	Результат = Результат + "Заголовки:" + Символы.ПС;
	Для каждого Параметр Из Запрос.Заголовки Цикл
		Результат = Результат + Параметр.Ключ + ":" + Параметр.Значение + Символы.ПС;
	КонецЦикла;
	Результат = Результат + Символы.ПС + "Параметры URL:" + Символы.ПС;
	Для каждого Параметр Из Запрос.ПараметрыURL Цикл
		Результат = Результат + Параметр.Ключ + ":" + Параметр.Значение + Символы.ПС;
	КонецЦикла;
	Результат = Результат + Символы.ПС + "Параметры запроса:" + Символы.ПС;
	Для каждого Параметр Из Запрос.ПараметрыЗапроса Цикл
		Результат = Результат + Параметр.Ключ + ":" + Параметр.Значение + Символы.ПС;
	КонецЦикла;
	Ответ.УстановитьТелоИзСтроки(Результат);
	
	//Ответ.Заголовки.Вставить("Content-Type","text/html; charset=utf-8");
	Ответ.Заголовки.Вставить("Content-Type","text/plain; charset=utf-8");

	Возврат Ответ
КонецФункции
Показать



Обращался так:
&НаСервере
Процедура ВсеМетодыНаСервере()
	перПорт = 0;
	перСервер = "127.0.0.1";
	перПользователь = "Администратор";
	перПароль = "";
	
	Попытка		
		Если перПорт <= 0 Тогда 
			HTTPСоединение = Новый HTTPСоединение(перСервер,,перПользователь,перПароль);
		Иначе 
			HTTPСоединение = Новый HTTPСоединение(перСервер,перПорт,перПользователь,перПароль);
		КонецЕсли;	
	Исключение
		Сообщить("Подключение не прошло по причине "+ОписаниеОшибки());
		
		//Подчичаем соединение
		HTTPСоединение = Неопределено;
		Возврат;
	КонецПопытки;
	
	МассивМетодов = МассивВсехМетодов();
	
	Для Каждого элМассива из МассивМетодов Цикл  
		
		Результат = Результат + "Метод: [" + элМассива + "]++" + Символы.ПС;
		перРесурсНаСервере = "/DemoSSL2_4_6_146/hs/PAPI/"+элМассива+"?parametr1=13¶metr2=test";
		
		Результат = Результат + "{Без тела запроса}" + Символы.ПС;
		HTTPЗапрос = Новый HTTPЗапрос(перРесурсНаСервере);
		//Тело отсутствует
		HTTPОтвет = HTTPСоединение.ВызватьHTTPМетод(элМассива,HTTPЗапрос);
		
		//Получаем ответный текст или текст ошибки
		Ответочка = HTTPОтвет.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);

		Результат = Результат + Ответочка + Символы.ПС + Символы.ПС;
		
		Результат = Результат + "{С телом запроса}" + Символы.ПС;
		//Тело присутствует
		HTTPЗапрос.УстановитьТелоИзСтроки("Тело Запроса - просто текст");
		HTTPОтвет = HTTPСоединение.ВызватьHTTPМетод(элМассива,HTTPЗапрос);
		
		//Получаем ответный текст или текст ошибки
		Ответочка = HTTPОтвет.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
		
		Результат = Результат + Ответочка + Символы.ПС;
		
		Результат = Результат +  "Метод: [" + элМассива + "]--" + Символы.ПС + Символы.ПС;
	КонецЦикла;	
		
КонецПроцедуры

&НаСервереБезКонтекста
Функция МассивВсехМетодов()
	МассивМетодов = новый Массив;
	МассивМетодов.Добавить("GET");
	МассивМетодов.Добавить("HEAD");
	МассивМетодов.Добавить("PUT");
	МассивМетодов.Добавить("POST");
	МассивМетодов.Добавить("DELETE");
	МассивМетодов.Добавить("PATCH");
	МассивМетодов.Добавить("MERGE");
	МассивМетодов.Добавить("OPTIONS");
	МассивМетодов.Добавить("TRACE");
	МассивМетодов.Добавить("CONNECT");
	Возврат МассивМетодов;
КонецФункции	
Показать




GET


HEAD


PUT


POST


DELETE


PATCH


MERGE


OPTIONS


TRACE


CONNECT
NewLifeMan; +1 Ответить
16. insurgut 207 25.12.18 13:03 Сейчас в теме
На примере взаимодействия с ProfitBase никак не мог заставить работать метод PATCH.

В результате, многие сервисы очень чувствительны в тому, что указывается в заголовках. На моем примере после исправления не

HTTPЗапрос.Заголовки.Вставить("Content-type", "application/x-www-form-urlencoded;charset=utf-8");


в корректный

HTTPЗапрос.Заголовки.Вставить("Content-type", "application/json");


все заработало.
17. Danila-Master 116 30.03.20 09:43 Сейчас в теме
У httpсоединения есть собственные методы put и patch. Это Записать() и Изменить() соответственно.

Чем они отличаются от ВызватьHTTPМетод()?
18. tnic001in 15.10.21 11:48 Сейчас в теме
Я использую как раз put и patch через Записать и Изменить, никаких траблов с ними не было и не надо танцев с заголовками. Платформа даже древняя - 1С:Предприятие 8.3 (8.3.12.1790)
А ВызватьHTTPМетод просто более универсальный, плюс ответ сразу в файл можно вывалить.

Пример ниже, не претендует на правильность кода)
Прикрепленные файлы:
Оставьте свое сообщение