Интеграция систем на платформе 1С:Предприятие с внешними приложениями через HTTP-сервисы стала повседневной задачей разработчика. При реализации таких механизмов часто возникает ключевой вопрос: как правильно передать параметры запроса от клиента и корректно обработать их на стороне сервера? В этой статье мы подробно разберем все доступные способы передачи данных, проанализируем нюансы безопасности и рассмотрим практические примеры кода для различных сценариев.
Прежде чем перейти к написанию кода, разберем взаимодействие объектов платформы. На стороне клиента (отправителя запроса) мы оперируем объектом HTTPЗапрос. На стороне сервера (принимающего HTTP-сервиса 1С) входящие данные сопоставляются с объектом HTTPСервисЗапрос.
Объект HTTPСервисЗапрос содержит свойство ПараметрыЗапроса, имеющее тип ФиксированноеСоответствие. Наша главная задача — сделать так, чтобы при вызове сервиса со стороны клиента это соответствие автоматически заполнялось нужными нам парами "ключ-значение".
Самый простой и интуитивно понятный способ передать параметры — это указать их непосредственно в строке запроса (URL) после символа знака вопроса (?). Если параметров несколько, они разделяются символом амперсанда (&). Например: /api/v1/get_data?param1=value1¶m2=value2.
Рассмотрим детальный пример формирования такого запроса на клиенте. Важный нюанс: любые текстовые параметры, передаваемые в URL, должны проходить обязательное кодирование. Если этого не сделать, спецсимволы (пробелы, кириллица, знаки & или ?) нарушат структуру запроса и приведут к ошибкам разбора на стороне веб-сервера. Для кодирования параметров мы будем использовать стандартную функцию платформы КодироватьСтроку с режимом СпособКодированияСтроки.URLПараметр.
// Код на стороне клиента (отправитель запроса)
&НаСервере
Процедура ВыполнитьHTTPЗапросНаСервере_GET()
АдресСервера = "api.myservice.ru";
// Безопасно кодируем значения параметров перед вставкой в URL
ЛогинКодированный = КодироватьСтроку("Иван Иванов", СпособКодированияСтроки.URLПараметр);
ПарольКодированный = КодироватьСтроку("SuperSecretPass!", СпособКодированияСтроки.URLПараметр);
// Формируем строку ресурса с параметрами запроса
АдресРесурса = СтрШаблон("/hs/Repairs/GetInfo?NameUser=%1&Password=%2", ЛогинКодированный, ПарольКодированный);
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json");
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);
// Инициализируем защищенное соединение SSL
Соединение = Новый HTTPСоединение(АдресСервера, 443, , , , 100, Новый ЗащищенноеСоединениеOpenSSL());
Попытка
РезультатHTTPОтвет = Соединение.Получить(HTTPЗапрос);
Если РезультатHTTPОтвет.КодСостояния = 200 Тогда
СтрокаОтвета = РезультатHTTPОтвет.ПолучитьТелоКакСтроку();
Сообщить("Ответ сервера: " + СтрокаОтвета);
Иначе
Сообщить("Ошибка сервера. Код ответа: " + РезультатHTTPОтвет.КодСостояния);
КонецЕсли;
Исключение
Сообщить("Ошибка соединения: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Теперь посмотрим, как обработать эти параметры на стороне принимающего HTTP-сервиса в модуле метода GET:
// Код модуля HTTP-сервиса 1С (сервер-получатель)
Функция RepairsGetInformation(Запрос)
// Платформа 1С автоматически разбирает параметры после знака "?"
// и помещает их в ФиксированноеСоответствие "ПараметрыЗапроса"
ИмяПользователя = Запрос.ПараметрыЗапроса.Получить("NameUser");
Пароль = Запрос.ПараметрыЗапроса.Получить("Password");
Если Не ЗначениеЗаполнено(ИмяПользователя) Или Не ЗначениеЗаполнено(Пароль) Тогда
Ответ = Новый HTTPСервисОтвет(400);
Ответ.УстановитьТелоИзСтроки("Не указаны обязательные параметры запроса!");
Возврат Ответ;
КонецЕсли;
// Логика обработки параметров на стороне базы данных...
Ответ = Новый HTTPСервисОтвет(200);
Ответ.УстановитьТелоИзСтроки("Авторизация успешна для пользователя: " + ИмяПользователя);
Возврат Ответ;
КонецФункции
Передача авторизационных или конфиденциальных данных (таких как пароли, токены доступа или персональные данные клиентов) в открытом виде внутри URL-адреса считается плохой практикой (моветоном) в веб-разработке. Это связано с тем, что URL-адреса часто логируются прокси-серверами, веб-серверами (IIS, Apache, Nginx) и сохраняются в истории сетевого оборудования.
Для безопасной и структурированной передачи сложных данных рекомендуется использовать POST-запросы, передавая параметры внутри тела запроса в формате JSON. Разберем, как реализовать этот подход на клиенте и сервере.
// Код на стороне клиента (отправитель POST-запроса)
&НаСервере
Процедура ВыполнитьHTTPЗапросНаСервере_POST()
АдресСервера = "api.myservice.ru";
АдресРесурса = "/hs/Repairs/VerifyUser";
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
// Формируем структуру параметров
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("NameUser", "Иван Иванов");
СтруктураПараметров.Вставить("Password", "SuperSecretPass!");
// Сериализуем структуру параметров в строку JSON
ЗаписьJS = Новый ЗаписьJSON;
ЗаписьJS.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJS, СтруктураПараметров);
ТелоЗапросаJSON = ЗаписьJS.Закрыть();
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапросаJSON, КодировкаТекста.UTF8);
Соединение = Новый HTTPСоединение(АдресСервера, 443, , , , 100, Новый ЗащищенноеСоединениеOpenSSL());
Попытка
// Для POST-запросов используется метод ОтправитьДляОбработки или универсальный ВызватьHTTPМетод
РезультатHTTPОтвет = Соединение.ОтправитьДляОбработки(HTTPЗапрос);
Если РезультатHTTPОтвет.КодСостояния = 200 Тогда
Сообщить(РезультатHTTPОтвет.ПолучитьТелоКакСтроку());
Иначе
Сообщить("Ошибка выполнения POST-запроса: " + РезультатHTTPОтвет.КодСостояния);
КонецЕсли;
Исключение
Сообщить("Ошибка связи с сервером: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
На стороне HTTP-сервиса нам потребуется прочитать тело запроса как строку и десериализовать её обратно в структуру 1С:
// Код модуля HTTP-сервиса (сервер-получатель POST)
Функция VerifyUserPOST(Запрос)
// Получаем тело POST-запроса в виде строки
СтрокаJSON = Запрос.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
Если Не ЗначениеЗаполнено(СтрокаJSON) Тогда
Ответ = Новый HTTPСервисОтвет(400);
Ответ.УстановитьТелоИзСтроки("Пустое тело запроса!");
Возврат Ответ;
КонецЕсли;
// Десериализуем JSON в структуру 1С
ЧтениеJS = Новый ЧтениеJSON;
ЧтениеJS.УстановитьСтроку(СтрокаJSON);
Попытка
ДанныеЗапроса = ПрочитатьJSON(ЧтениеJS);
Исключение
Ответ = Новый HTTPСервисОтвет(400);
Ответ.УстановитьТелоИзСтроки("Некорректный формат JSON!");
Возврат Ответ;
КонецПопытки;
ЧтениеJS.Закрыть();
// Извлекаем параметры по ключам структуры
ИмяПользователя = "";
Пароль = "";
ДанныеЗапроса.Свойство("NameUser", ИмяПользователя);
ДанныеЗапроса.Свойство("Password", Пароль);
// Логика проверки пользователя...
Ответ = Новый HTTPСервисОтвет(200);
Ответ.УстановитьТелоИзСтроки("Данные успешно обработаны.");
Возврат Ответ;
КонецФункции
Современным архитектурным стандартом построения API является стиль REST. В рамках этого подхода идентификаторы ресурсов или ключевые параметры передаются непосредственно в сегментах URL-пути (URI). Например, вместо запроса /hs/orders?id=12345 мы пишем красивый адрес /hs/orders/12345.
Для реализации этого механизма в свойствах шаблона URL нашего HTTP-сервиса в конфигураторе 1С необходимо задать шаблон вида: /orders/{OrderNumber}. Фигурные скобки указывают платформе, что данная часть пути является переменной.
На стороне клиента мы просто вызываем этот адрес:
АдресРесурса = "/hs/Repairs/orders/RU-005823";
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);
На стороне сервера платформа автоматически сопоставит сегмент пути со свойством ПараметрыШаблона (тип Соответствие):
НомерЗаказа = Запрос.ПараметрыШаблона.Получить("OrderNumber"); // Возвратит строку "RU-005823"
Этот подход делает структуру API чистой, логичной и чрезвычайно удобной для интеграции с внешними веб-приложениями.
Помимо стандартной передачи параметров в строке или теле JSON, разработчики часто сталкиваются с нестандартными или высоконагруженными сценариями. Рассмотрим три важнейших аспекта:
HTTPЗапрос.Заголовки.Вставить(). На сервере они доступны через аналогичное свойство.HTTPЗапрос.УстановитьТелоИзФайла() на клиенте, а на сервере извлекайте файл через Запрос.ПолучитьТелоКакДвоичныеДанные().Пользователь и Пароль при инициализации HTTPСоединение. Платформа самостоятельно сгенерирует заголовок Authorization: Basic..., а проверка прав произойдет на уровне веб-сервера еще до запуска кода HTTP-сервиса, что гарантирует максимальную безопасность.Подводя итог, выберем оптимальный метод передачи параметров для ваших интеграционных задач:
?). Не забывайте использовать КодироватьСтроку!