Как сделать HTTPСоединение вместо WinHttpRequest?

1. EvgeTrofi 127 01.03.20 08:26 Сейчас в теме
Добрый день.
Имеется рабочий код, передающий XML строку на сайт и получающий от сайта ответ в XML строку, реализованный на COM-объекте WinHttpRequest:
	WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
	WinHttp.Option(2,"utf-8");
	WinHttp.Open("POST",Адрес,0);
	WinHttp.SetRequestHeader("User-Agent", "1C Soap toolkit");
	WinHttp.SetRequestHeader("Content-Type","text/xml;charset=UTF-8");
	WinHttp.setRequestHeader("SOAPAction", "http://tempuri.org/" + Процедура_);
	WinHttp.setRequestHeader("Content-Length", Формат(СтрДлина(ТекстXML),"ЧГ=0"));
	WinHttp.setRequestHeader("Accept-Encoding", "text");
	WinHttp.Send(ТекстXML);
	Сообщить("Код состояния: "+WinHttp.status());
	Stream = Новый COMОбъект("ADODB.Stream");
	Stream.Type = 1;
	Stream.Mode = 3;	
	ВремФайл = ПолучитьИмяВременногоФайла("xml");
	Stream.Open();
	Stream.Write(WinHttp.ResponseBody);
	Stream.SaveToFile(ВремФайл, 2);
	Stream.Close();
	ЧТ = Новый ЧтениеТекста(ВремФайл);
	ОтветXML = ЧТ.Прочитать();
	ЧТ.Закрыть();
	УдалитьФайлы(ВремФайл);
Показать

В результате выполнения этого фрагмента кода я получаю код состояния 200 и адекватный ответ от сервера в виде XML строки.

Задача: Требуется отказаться от COM-объектов и, используя только средства 1С, выполнить аналогичные действия.

Я использовал следующее:
	Заголовки = Новый Соответствие;
	Заголовки.Вставить("User-Agent", "1C Soap toolkit");
	Заголовки.Вставить("Content-Type", "text/xml;charset=UTF-8");
	Заголовки.Вставить("SOAPAction", "http://tempuri.org/" + Процедура_);
	Заголовки.Вставить("Content-Length", Формат(СтрДлина(ТекстXML),"ЧГ=0"));
	Заголовки.Вставить("Accept-Encoding", "text");

	HTTPСоединение = Новый HTTPСоединение(СерверДанных,,,,,120);
	HTTPЗапрос = Новый HTTPЗапрос(ПутьДоWSDL, Заголовки);
	HTTPЗапрос.УстановитьТелоИзСтроки(ТекстXML, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
	HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос); //POST запрос
	Для Каждого ЗаголовокОтвета Из HTTPОтвет.Заголовки Цикл
		Сообщить(ЗаголовокОтвета.Ключ + " = " + ЗаголовокОтвета.Значение);
	КонецЦикла;
	Сообщить("Код состояния = "+HTTPОтвет.КодСостояния);	
	ОтветXML = HTTPОтвет.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
Показать

В результате получил Код состояния 400, а в ОтветXML - пустую строку.

Помогите пожалуйста разобраться, в чём же дело?
Естественно, что ТекстXML в обоих вариантах имеет одно и то же значение.
Найденные решения
4. a30v 03.03.20 11:19 Сейчас в теме
(3) Попробуйте с помощью Fiddler отследить что отправляет WinHttpRequest. WSОпределения не будет в данном случае лучшим вариантом?
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. a30v 03.03.20 00:52 Сейчас в теме
А если без Content-Length отправить? Попробуйте отправить свой запрос с использованием Postman.
3. EvgeTrofi 127 03.03.20 08:40 Сейчас в теме
(2) Postman мне дополнил список рекомендуемых полей Headers (в том числе и Content-Length), но возвращает ту же самую ошибку:
HTTP Error 400. The request is badly formed.

Возможно, WinHttpRequest совершает какую-то магию, которую не умеет HTTPСоединение и Postman.
Написал в службу поддержки сервиса. Буду ждать ответа.
4. a30v 03.03.20 11:19 Сейчас в теме
(3) Попробуйте с помощью Fiddler отследить что отправляет WinHttpRequest. WSОпределения не будет в данном случае лучшим вариантом?
5. EvgeTrofi 127 03.03.20 12:23 Сейчас в теме
(4) Не понял, что такое Fiddler, но на счёт WSОпределения Вы правы. Всё получилось именно так:
Функция ПолучитьВебСервис(ВызыватьИсключение = Истина) Экспорт
	URLИсточника 			= "Адрес к WSDL";
	МестоположениеИсточника = "Адрес к WSDL";
	ЭтоСоединениеSSL = СтрНачинаетсяС(URLИсточника, "https");
	Если ЭтоСоединениеSSL Тогда
		СисИнфо  = Новый СистемнаяИнформация;
		Если (СисИнфо.ТипПлатформы = ТипПлатформы.Windows_x86)
			Или (СисИнфо.ТипПлатформы = ТипПлатформы.Windows_x86_64) Тогда
			ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(
				Новый СертификатКлиентаWindows(),
				Новый СертификатыУдостоверяющихЦентровWindows());
		Иначе
			ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
		КонецЕсли;
	Иначе
		ЗащищенноеСоединение = Неопределено;
	КонецЕсли;
	
	Таймаут = 1000;
	
	Попытка
		WSОпределения = Новый WSОпределения(URLИсточника,,,, Таймаут, ЗащищенноеСоединение);
		Прокси = Новый WSПрокси(WSОпределения, "http://tempuri.org/", "AccountingTransfer", "AccountingTransferSoap",, Таймаут, ЗащищенноеСоединение,МестоположениеИсточника);
	Исключение
		Инфо = ИнформацияОбОшибке();
		Сообщить("" + ПодробноеПредставлениеОшибки(Инфо));
		Если ВызыватьИсключение Тогда
			ВызватьИсключение "Ошибка подключения к сервису. Обратитесь к администратору системы.";
		Иначе
			Возврат Неопределено;
		КонецЕсли;
	КонецПопытки;
	
	СтруктураОтвета = Новый Структура;
	СтруктураОтвета.Вставить("Прокси",Прокси);
	СтруктураОтвета.Вставить("Определения",WSОпределения);
	
	Возврат СтруктураОтвета;
КонецФункции // ПолучитьВебСервис()
Показать


Спасибо!
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот