Универсальный механизм общения с внешним миром. HTTPЗапрос POST / GET / JSON

28.06.16

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

Умеет 1С общаться с внешним миром. Мне кажется, не совсем удобно пользоваться тем функционалом, что дали нам разработчики платформы. И решил тогда (копируя из раза в раз однотипные куски кода) написать себе универсальный велосипед.
Что он умеет:
Отправлять запросы GET - просто строка с адресом
Отправлять запросы POST - адрес + строка(ки) содержимого
Преобразовать отправляемые данные формата JSON
Принимать данные в строку, или через файл. Если данных много, но всё равно потом записывать в переменную содержимое файла.
Принимать бинарные/картинки. Принимает, но отдаёт их строкой. Нужно взять напильник и подточить функцию.

Пользовать начиная с платформы - 8.3.6

Решение:

Функция ВыполнитьЗапрос(Параметры) Экспорт
	
	Ответ = Новый Структура("Код, ДанныеОтвета",0,"");
	//Получим хост
	АдресДл = Параметры.УРЛ;
	АдресДл = СтрЗаменить(АдресДл, "https://" ,"");  
	АдресДл = СтрЗаменить(АдресДл, "http://" ,"");  
	индексСлеша  = Найти(АдресДл, "/");
	ХОСТ = АдресДл;
	Если индексСлеша > 0 Тогда
		ХОСТ = Сред(АдресДл, 1 ,индексСлеша - 1);
	КонецЕсли;
	
	// вычислить строку URL
	длинаСтроки = СтрДлина(АдресДл);
	Ресурс = "/" + Прав(АдресДл, длинаСтроки -  индексСлеша);
	
	Порт        = 80;  ssl = Неопределено; 
	Если Параметры.Свойство("Логин") Тогда 
	    Если Найти(ВРег(Параметры.УРЛ), ВРег("https")) > 0 Тогда 
	        Порт = 443;
	        ssl = Новый ЗащищенноеСоединениеOpenSSL( неопределено, неопределено ); 
		КонецЕсли;
		HTTPСоединение =  Новый HTTPСоединение(ХОСТ, Порт, 
		Параметры.Логин,  Параметры.Пароль,,, ssl); 
	Иначе
		HTTPСоединение =  Новый HTTPСоединение(ХОСТ,,,,,);
	КонецЕсли;
	
	
	//ФайлЗапроса = ПолучитьИмяВременногоФайла();    
	// Преобразуем типы платформы в JSON  
	ТелоЗапроса = Истина;
	Если Параметры.Свойство("Тело") Тогда
		ТелоЗапроса = Параметры.Тело; 
	ИначеЕсли Параметры.Свойство("ТелоJSon") Тогда
		СтрокаJSON = Новый ЗаписьJSON; СтрокаJSON.УстановитьСтроку();
		ЗаписатьJSON(СтрокаJSON, Параметры.ТелоJSon);
		ТелоЗапроса = СтрокаJSON.Закрыть(); 
	КонецЕсли;
		
	
	КодСостояния = 0;
	ОтветСервера = "";
	
	ЗаголовокHTTP = Новый Соответствие();
	ЗаголовокHTTP.Вставить("Host", Хост);
	Если Параметры.Свойство("Заголовок") Тогда
		Для Каждого ЭлементЗ из Параметры.Заголовок Цикл 
			ЗаголовокHTTP.Вставить(ЭлементЗ.Парам, ЭлементЗ.Знч);
		КонецЦикла;	
	КонецЕсли;
	
	
	Попытка
		ФайлОтвета	= Неопределено;
		Если (Параметры.Свойство("ЧерезФайл")) Тогда 
			ФайлОтвета	= ПолучитьИмяВременногоФайла(Параметры.ЧерезФайл);	
		КонецЕсли;
		
		HTTPЗапрос	= Новый HTTPЗапрос(Ресурс, ЗаголовокHTTP);
		HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8);
		
		Если ((Параметры.Свойство("Способ")) и (Врег(Параметры.Способ) = "POST"))
				или
			(Параметры.Свойство("Тело")) или (Параметры.Свойство("ТелоJSon"))
			Тогда 
				Если (Параметры.Свойство("ЧерезФайл")) Тогда 
					HTTPОтвет	= HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос, ФайлОтвета);
				Иначе
					HTTPОтвет	= HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
				КонецЕсли;
		Иначе
			HTTPОтвет	= HTTPСоединение.Получить(HTTPЗапрос);
		КонецЕсли;
		
		ДанныеОтвета = "";
		Ответ.Вставить("Код", HTTPОтвет.КодСостояния);
		Если Ответ.Код = 200 Тогда
			Если (Параметры.Свойство("ЧерезФайл")) Тогда 
				Если Параметры.Свойство("ОтветJSON") Тогда
					Чтение = Новый ЧтениеJSON;
					Чтение.ОткрытьФайл(ФайлОтвета);
					ДанныеОтвета = ПрочитатьJSON(Чтение, Ложь);
					Чтение.Закрыть();
				Иначе
					Файл = Новый ЧтениеТекста(ФайлОтвета);
					ДанныеОтвета = Файл.Прочитать();
					Файл.Закрыть();
				КонецЕсли;
				Попытка
					УдалитьФайлы(ФайлОтвета);
				Исключение
				КонецПопытки;
			Иначе
				Если Параметры.Свойство("ОтветJSON") Тогда
					ДанныеОтвета = HTTPОтвет.ПолучитьТелоКакСтроку();
					Чтение = Новый ЧтениеJSON;
					Чтение.УстановитьСтроку(ДанныеОтвета);
					ДанныеОтвета = ПрочитатьJSON(Чтение, Ложь);
					Чтение.Закрыть();
				Иначе
					ДанныеОтвета = HTTPОтвет.ПолучитьТелоКакСтроку();
				КонецЕсли;
			КонецЕсли;
			
			
		КонецЕсли;
		
		Ответ.Вставить("ДанныеОтвета", ДанныеОтвета);
	Исключение
		Сообщить("Не удалось установить соединение с сервером :" 
		+ Символы.ПС + ИнформацияОбОшибке().Описание, СтатусСообщения.Важное);
	КонецПопытки;
	
	Возврат Ответ;
	
КонецФункции

 

Пример вызова:

параметры:

Заголовок - Если нужен хитрый заголовок, указываем свои параметры, см. ниже.

УРЛ - Полный путь к ресурсу

Логин/Пароль - Пользовать парой, указывает на работут через basic authentication

ОтветJSON - Просим преобразовать ответ в струкруты, массивы, объекты 1С

ЧерезФайл - Указывает принять запрос через файл. (для большого ответа. Например последующее чтение JSON)

 

		Заголовок		= Новый Массив();
		Заголовок.Добавить( Новый Структура("Парам, Знч",	"Content-Type",		"application/json") );
		Заголовок.Добавить( Новый Структура("Парам, Знч",	"Accept",		"application/json; utf-8;") );
		Заголовок.Добавить( Новый Структура("Парам, Знч",	"Accept-Charset",	"utf-8;") );
		
		Парам = новый Структура();
		Парам.Вставить("Заголовок", Заголовок);
		Парам.Вставить("УРЛ", "https://www.google.ru"+"/?gfe_rd=cr&ei=L3ByV96dD-KWwAPrloEg&gws_rd=ssl#newwindow=1&q=Василий Алибабаевич");
		
		ОтветСодержимое = ВыполнитьЗапрос(Парам);

HTTPЗапрос JSON прочитать содержимое страницы получить файл из интернет

См. также

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

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

12000 руб.

02.09.2020    169275    937    403    

905

Запросы Программист Бесплатно (free)

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    11394    sergey279    18    

65

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

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    6338    XilDen    36    

83

Запросы Программист Запросы Бесплатно (free)

Отлаживая взаимодействие с базой данных, мы регулярно сталкиваемся с зависающими или подозрительно долго выполняющимися обращениями, негативно влияющими на производительность. О том, как в PostgreSQL выявить подозрительные запросы, основываясь на доступной о них информации, расскажем в статье.

16.08.2024    9068    user1840182    5    

28

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

Рассмотрим быстрый алгоритм поиска дублей с использованием hash функции по набору полей шапки и табличных частей.

08.07.2024    2727    ivanov660    9    

22

Запросы СКД Программист Стажер Система компоновки данных Россия Бесплатно (free)

Часто при разработке отчетов в СКД возникает ситуация, когда не совсем понятно, почему отчет выводит не те данные, которые нужны, либо не выводит вовсе. Возникает потребность увидеть конечный запрос, который формирует СКД. Как это сделать, рассмотрим в этой статье.

15.05.2024    10219    implecs_team    6    

48

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

Часто поступают задачи по произвольному распределению общих сумм. После распределения иногда пропадают копейки. Суть решения добавить АвтоНомерЗаписи() в ВТ распределения, и далее используя функции МАКСИМУМ или МИНИМУМ можем положить разницу копеек в первую или последнюю строку знаменателя распределения.

11.04.2024    3623    andrey_sag    10    

38
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. neyasytyf 29.06.16 08:24 Сейчас в теме
2. agent00mouse 257 29.06.16 08:39 Сейчас в теме
(1) neyasytyf, Наверняка 8.3. Значит со временем функция мутировала. Спасибо.
3. Lenten 25 30.06.16 17:35 Сейчас в теме
1) Чето у меня ругается. Платформа 1С:Предприятие 8.3 (8.3.5.1517)

{Форма.Форма.Форма(55,28)}: Тип не определен (ЗаписьJSON)
СтрокаJSON = Новый <<?>>ЗаписьJSON; СтрокаJSON.УстановитьСтроку(); (Проверка: Толстый клиент (обычное приложение))
{Форма.Форма.Форма(100,36)}: Тип не определен (ЧтениеJSON)
Чтение = Новый <<?>>ЧтениеJSON; (Проверка: Толстый клиент (обычное приложение))
{Форма.Форма.Форма(116,36)}: Тип не определен (ЧтениеJSON)
Чтение = Новый <<?>>ЧтениеJSON; (Проверка: Толстый клиент (обычное приложение))
2) А что будет логином и паролем в случае с гуглом. Я вообще в этом не секу )
4. agent00mouse 257 30.06.16 20:24 Сейчас в теме
(3) Lenten, Логин и пароль были вырваны из контекста, просто для примера.
ЧтениеJSON - появился в платформе начиная с релиза 8.3.6...
5. depresnjak 3 05.07.16 00:58 Сейчас в теме
Как по мне, то тема https и ssl раскрыта не полностью.
6. agent00mouse 257 05.07.16 09:52 Сейчас в теме
(5) depresnjak, Согласен, Мне базовой уровень авторизации пока было достаточно. Есть наработка по авторизации через сертификат, Всё выльется в небольшую библиотеку.
Будут просьбы расширить функционал, постараюсь дописать.
7. sss999 48 11.07.16 23:01 Сейчас в теме
Можешь подсказать по коду?
8. agent00mouse 257 12.07.16 08:00 Сейчас в теме
9. adhocprog 1143 03.08.16 15:48 Сейчас в теме
Спасибо! Полезный материал )
10. unpete 577 08.08.16 15:56 Сейчас в теме
Порты 80 и 443, наверное, следует задавать только в том случае, если они не указаны в url.
Ваш код отработает с ошибкой для запроса вида https://mysite.com:8359/data.json#private
11. agent00mouse 257 10.08.16 21:13 Сейчас в теме
(10) unpete, (10) unpete, Дельное замечание. поправлю.
12. Stepa86 1532 01.09.16 12:50 Сейчас в теме
В УП и видимо в других конфах со встроенной библиотекой интернет-поддержки пользователей есть метод
ИнтернетПоддержкаПользователейКлиентСервер.ЗагрузитьСодержимоеИзИнтернет(
	Знач URL,
	Знач Логин = Неопределено,
	Знач Пароль = Неопределено,
	ДопПараметры = Неопределено) Экспорт
13. Djo82 12 27.03.18 09:21 Сейчас в теме
Здравствуйте! не могли бы помочь, не могу понять как должен выглядеть параметр:
ТелоЗапроса, не получается заменить значения на сайте методом post

HTTPЗапрос    = Новый HTTPЗапрос(Ресурс, ЗаголовокHTTP);
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8);


МассивДанныхJSON = Новый Массив;
    СтруктураДанныхJSON = Новый Структура; 
	тДанные = Новый Структура;
    тДанные.Вставить("managerComment", "тестКомментарий23");
	тДанные.Вставить("phone", 8888888);
    МассивДанныхJSON.Добавить(тДанные);
    	
	СтрокаJSON = Новый ЗаписьJSON; 
	СтрокаJSON.УстановитьСтроку();
    ЗаписатьJSON(СтрокаJSON, МассивДанныхJSON);
    ТелоЗапроса = СтрокаJSON.Закрыть(); 
	Параметры.ТекстЗапроса = ТелоЗапроса;
//////
Показать

сама строка методом get:

{"error":"","errorMessage":"","result":[{"userType":1,"managerID":"1","managerLogin":"manager","officeID":"1","officeName":"Нскойл","customerID":"1","customerExternalID":null,"categoryID":"1","categoryName":"розница","name":null,"secondName":null,"surname":null,"fullName":"","login":null,"phone":null,"mobilePhone":null,"email":null,"icq":null,"skype":null,"country":null,"region":null,"city":null,"organizationName":"Нскойл","businessID":null,"businessName":null,"balance":"0.00","creditLimit":null,"managerComment":null,"contragentType":"2","organizationFormID":null,"organizationFormName":null,"groupID":null,"groupName":null,"aiBalanceOrdered":"0.00","aiBalanceActiveOrdered":"0.00","aiBalanceTotal":"0.00","aiBalanceByReturn":"0.00","aiBalanceDelayed":"0.00"}]}
14. Djo82 12 30.03.18 10:57 Сейчас в теме
(13) Сам спросил, сам отвечу)
Возможно кому то понадобиться:
Думал проблема с написанием текста запроса, оказалось с кодировкой

Заголовок1.Добавить( Новый Структура("Парам, Знч",    "Content-Type",        "application/json") );


заменил на

Заголовок1.Добавить( Новый Структура("Парам, Знч",    "Content-Type",        "application/x-www-form-urlencoded;charset=utf-8") );

и
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8);


заменил на

HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса,КодировкаТекста.UTF8,ИспользованиеByteOrderMark.НеИспользовать);
wunderland; hasp_x; +2 Ответить
15. agent00mouse 257 08.04.18 10:24 Сейчас в теме
Вот оно как! ;-)
Прошу прощения, что сам не успел ответить. Не было времени. (отмазка)
16. Lion_LexXx 1 26.08.19 14:27 Сейчас в теме
Получение IAM-токена с помощью PowerShell:

$yandexPassportOauthToken = "<OAuth-Token>"
$Body = @{ yandexPassportOauthToken = "$yandexPassportOauthToken" } | ConvertTo-Json -Compress
Invoke-RestMethod -Method 'POST' -Uri 'https://iam.api.cloud.yandex.net/iam/v1/tokens' -Body $Body -ContentType 'Application/json' | Select-Object -ExpandProperty iamToken

Как это переделать на 1С?
17. Lion_LexXx 1 27.08.19 06:04 Сейчас в теме
(16)
https://infostart.ru/public/1113219/

    АдресСервера = "iam.api.cloud.yandex.net";    
    yandexPassportOauthToken = "ХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХ";     
    ssl = Новый ЗащищенноеСоединениеOpenSSL(Новый СертификатКлиентаWindows( СпособВыбораСертификатаWindows.Выбирать), Новый СертификатыУдостоверяющихЦентровWindows());     
    

    Соединение = Новый HTTPСоединение(АдресСервера,443,,,,20,ssl,Неопределено);    
    Заголовки = Новый Соответствие;
    Заголовки.Вставить("Content-Type", "application/json");
    
    Запрос = Новый HTTPЗапрос("/iam/v1/tokens",Заголовки);    
    СтрокаТела = "{""yandexPassportOauthToken"": """ + yandexPassportOauthToken + """}";
    Запрос.УстановитьТелоИзСтроки(СтрокаТела,КодировкаТекста.UTF8);

    
    Ответ = Соединение.ОтправитьДляОбработки(Запрос); 
    Сообщить("Нам вернули код " + Ответ.КодСостояния);
    Сообщить(Ответ.ПолучитьТелоКакСтроку());
    
    СтрокаОтвет = Ответ.ПолучитьТелоКакСтроку();
    
    Чтение = Новый ЧтениеJSON;
    Чтение.УстановитьСтроку(СтрокаОтвет);
    СтруктураОтвета = ПрочитатьJSON(Чтение);
    iamToken = СтруктураОтвета.iamToken;
Показать
Maxmudjon; +1 Ответить
Оставьте свое сообщение