При интеграции 1С со сторонними веб-сервисами и API часто возникает задача отправки HTTP-запроса и последующей обработки полученного ответа. Веб-серверы обычно возвращают данные в формате JSON. Разберем по шагам, как правильно преобразовать строку JSON в структуру или соответствие средствами платформы 1С, а также рассмотрим особенности работы с COM-объектом WinHttp.WinHttpRequest.5.1 и современные штатные альтернативы.
Начиная с версии платформы 8.3.6, в 1С реализована встроенная поддержка работы с форматом JSON. Для десериализации (преобразования строки JSON в объекты 1С) используется объект ЧтениеJSON и системная функция ПрочитатьJSON().
Рассмотрим подробнее стандартный алгоритм обработки ответа:
ЧтениеJSON.УстановитьСтроку().ПрочитатьJSON(), передавая ей объект чтения.Закрыть().Посмотрим на практический пример функции, которая принимает JSON-строку и возвращает структуру 1С:
Функция ПреобразоватьJSONВСтруктуру(Знач СтрокаJSON) Экспорт
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);
Результат = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
Возврат Результат;
КонецФункции
Если передать в эту функцию строку {"status":"ok","ballance":"50.00","user_id":1584}, на выходе мы получим объект Структура с соответствующими ключами и значениями, к которым можно обращаться стандартным способом: Результат.status, Результат.ballance и Результат.user_id.
Проанализируем ситуацию, когда имена свойств в JSON содержат спецсимволы, дефисы, пробелы или начинаются с цифры (например, {"user-id": 1584, "1st_field": "test"}). Имена ключей в Структуре 1С подчиняются правилам формирования идентификаторов встроенного языка, поэтому при попытке разобрать такой JSON в структуру платформа вызовет исключение.
Чтобы избежать ошибки, во второй параметр функции ПрочитатьJSON() передается флаг Истина (чтение объектов JSON в Соответствие):
Функция ПреобразоватьJSONВСоответствие(Знач СтрокаJSON) Экспорт
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);
// Второй параметр Истина указывает читать JSON-объекты как Соответствие
Результат = ПрочитатьJSON(Чтение, Истина);
Чтение.Закрыть();
Возврат Результат;
КонецФункции
В данном случае обращение к элементам будет происходить через получение значения по ключу: Результат["user-id"].
При использовании COM-объекта WinHttp.WinHttpRequest.5.1 разработчики часто сталкиваются с двумя критическими проблемами:
ResponseText может вернуть искаженные кириллические символы («кракозябры»), если сервер не вернул явный заголовок с указанием кодировки. В таком случае надежнее получать бинарные данные через ResponseBody и декодировать их в строку 1С через ДвоичныеДанные или объект ADODB.Stream.Новый COMОбъект("WinHttp.WinHttpRequest.5.1") приведет к аварийному завершению с ошибкой.В современной разработке рекомендуется полностью отказаться от COM-объекта WinHttp в пользу штатных объектов платформы: HTTPСоединение, HTTPЗапрос и HTTPОтвет.
Посмотрим на пример отправки запроса и разбора ответа штатными средствами платформы:
Функция ВыполнитьЗапросКСерверу(Знач Сервер, Знач Ресурс) Экспорт
Соединение = Новый HTTPСоединение(Сервер, 443, , , , 30, Новый ЗащищенноеСоединениеOpenSSL());
Запрос = Новый HTTPЗапрос(Ресурс);
Запрос.Заголовки.Вставить("Accept", "application/json");
Ответ = Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 200 Тогда
СтрокаJSON = Ответ.ПолучитьТелоКакСтроку("UTF-8");
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);
Данные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
Возврат Данные;
Иначе
ВызватьИсключение "Ошибка HTTP-запроса: " + Ответ.КодСостояния;
КонецЕсли;
КонецФункции
Преимущества штатного подхода: метод ПолучитьТелоКакСтроку() гарантирует корректную работу с кодировкой UTF-8, код полностью кроссплатформенен и работает как на клиенте, так и на сервере под любой операционной системой.