Универсальный механизм общения с внешним миром. 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 прочитать содержимое страницы получить файл из интернет

См. также

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

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

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

13000 руб.

02.09.2020    119909    656    389    

701

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

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

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

13.02.2024    5618    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    6089    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    5282    user1923546    26    

43

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

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

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

11.10.2023    15954    skovpin_sa    14    

97
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. neyasytyf 29.06.16 08:24 Сейчас в теме
2. agent00mouse 252 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 252 30.06.16 20:24 Сейчас в теме
(3) Lenten, Логин и пароль были вырваны из контекста, просто для примера.
ЧтениеJSON - появился в платформе начиная с релиза 8.3.6...
5. depresnjak 2 05.07.16 00:58 Сейчас в теме
Как по мне, то тема https и ssl раскрыта не полностью.
6. agent00mouse 252 05.07.16 09:52 Сейчас в теме
(5) depresnjak, Согласен, Мне базовой уровень авторизации пока было достаточно. Есть наработка по авторизации через сертификат, Всё выльется в небольшую библиотеку.
Будут просьбы расширить функционал, постараюсь дописать.
7. sss999 48 11.07.16 23:01 Сейчас в теме
Можешь подсказать по коду?
8. agent00mouse 252 12.07.16 08:00 Сейчас в теме
9. adhocprog 1138 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 252 10.08.16 21:13 Сейчас в теме
(10) unpete, (10) unpete, Дельное замечание. поправлю.
12. Stepa86 1520 01.09.16 12:50 Сейчас в теме
В УП и видимо в других конфах со встроенной библиотекой интернет-поддержки пользователей есть метод
ИнтернетПоддержкаПользователейКлиентСервер.ЗагрузитьСодержимоеИзИнтернет(
	Знач URL,
	Знач Логин = Неопределено,
	Знач Пароль = Неопределено,
	ДопПараметры = Неопределено) Экспорт
13. Djo82 6 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 6 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 252 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 Ответить
Оставьте свое сообщение