Как передать одномерный массив строковых данных в параметрах HTTP-GET запроса из 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Передача сложных структур данных, таких как массивы, через параметры HTTP-GET запроса может быть нетривиальной задачей. Традиционно параметры GET запроса предназначены для простых значений. Однако, на практике часто возникает необходимость передать список значений, например, идентификаторы или коды, в виде массива. Рассмотрим, как эффективно решить эту проблему в 1С, используя подход с JSON-сериализацией, который был успешно применен на форуме, а также изучим альтернативные методы и важные аспекты.

Особенности передачи массивов в GET-параметрах

Когда мы работаем с HTTP-GET запросами, параметры передаются непосредственно в URL после знака вопроса (?) в формате ключ=значение, разделенные амперсандами (&) — в этом поможет инструмент логирования и анализа HTTP-запросов 1С. Основная проблема с массивами заключается в том, что HTTP-спецификация не предоставляет прямого и универсального способа для их передачи в таком формате. Различные фреймворки и языки программирования могут по-разному интерпретировать параметры, предназначенные для массивов.

Наш клиент, выполняющий запрос, использует 1С, и целевой HTTP-сервис также реализован на платформе 1С — для этого подойдёт модуль REST API для интеграции 1С. Это означает, что мы можем контролировать процесс как на стороне отправки, так и на стороне приема, что значительно упрощает выбор метода.

Решение проблемы с использованием JSON-сериализации

Один из наиболее гибких и надежных способов передачи массивов, особенно если они содержат строковые данные или более сложные структуры, — это преобразование (сериализация) массива в строку формата JSON, а затем передача этой JSON-строки как значения одного из параметров запроса — для этой задачи есть выгрузка данных из 1С через REST API. На стороне приема мы, соответственно, десериализуем эту строку обратно в массив.

Шаг 1: Формирование JSON-строки на стороне клиента (Отправляющая 1С)

Первым делом нам нужно преобразовать наш одномерный массив строковых данных в JSON-строку. В 1С для этого есть удобные инструменты. Рассмотрим пример функции, которая выполняет эту задачу:


Функция СформироватьJSON(МассивИсходныхДанных)
    
    // Создаем новый объект для записи JSON
    ЗаписьJSON = Новый ЗаписьJSON;
    
    // Устанавливаем параметры записи JSON.
    // ПереносСтрокJSON.Нет - для формирования компактной строки без лишних пробелов и переносов.
    // Истина - означает, что запись должна выполняться в одну строку.
    ЗаписьJSON.УстановитьСтроку(Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет,, Истина));
    
    // Настраиваем параметры сериализации, если это необходимо.
    // В данном случае, для массива строк, настройки даты не критичны,
    // но их можно указать для унификации стиля.
    НастройкиСериализацииJSON = Новый НастройкиСериализацииJSON;
    НастройкиСериализацииJSON.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.ЛокальнаяДата; // Пример настройки даты
    НастройкиСериализацииJSON.ФорматСериализацииДаты = ФорматДатыJSON.ISO;         // Пример настройки даты
    
    // Записываем наш массив в JSON-формат.
    // ЗаписатьJSON умеет работать с различными типами данных, включая массивы.
    ЗаписатьJSON(ЗаписьJSON, МассивИсходныхДанных, НастройкиСериализацииJSON);
    
    // Завершаем запись и получаем готовую JSON-строку.
    Возврат ЗаписьJSON.Закрыть();
    
КонецФункции

Предположим, у нас есть массив значений МассивИГК, который содержит строковые идентификаторы, например, МассивИГК = Новый Массив("1821187324101442209201989105456", "другойИдентификатор", "третийИдентификатор");. Вызов этой функции Json_МассивИГК = СформироватьJSON(МассивИГК); вернет строку, подобную следующей: ["1821187324101442209201989105456", "другойИдентификатор", "третийИдентификатор"].

Важный момент: URL-кодирование JSON-строки

Критически важно перед включением JSON-строки в URL выполнить ее URL-кодирование. Это необходимо для корректной передачи специальных символов (таких как пробелы, амперсанды, квадратные скобки, кавычки, знаки равенства и т.д.), которые могут быть неправильно интерпретированы в URL. Например, квадратные скобки ([ ]) и кавычки (") являются частью JSON-формата, но в URL они являются специальными символами и должны быть закодированы.

В 1С для URL-кодирования используется функция ПроцентноеКодирование(). Пример:


ИсходнаяJSONСтрока = СформироватьJSON(МассивИГК);
КодированнаяJSONСтрока = ПроцентноеКодирование(ИсходнаяJSONСтрока, КодировкаURL.UTF8);

// Теперь КодированнаяJSONСтрока может быть добавлена в URL:
// Например, если ИсходнаяJSONСтрока была '["123", "456"]',
// то КодированнаяJSONСтрока будет примерно '%5B%22123%22%2C%20%22456%22%5D'
// (точное кодирование зависит от символов и кодировки)

После этого вы можете сформировать полный URL для GET-запроса, добавив КодированнаяJSONСтрока в качестве значения параметра masigk:


БазовыйURL = "https://1cw.servak.ru/testbaza/hs/saleapi/salesmk?";
Параметры = Новый Соответствие();
Параметры.Вставить("org", "6672227222");
Параметры.Вставить("datestart", "20210111");
Параметры.Вставить("dateend", "20210411");
Параметры.Вставить("masigk", КодированнаяJSONСтрока); // Здесь используем уже закодированную строку

// Сформируем итоговый URL из коллекции параметров
// HTTPКлиент обычно автоматически кодирует значения параметров при использовании коллекции
HTTPКлиент = Новый HTTPКлиент();
HTTPЗапрос = Новый HTTPЗапрос();
HTTPЗапрос.УстановитьПараметрыЗапроса(Параметры);
ПолныйURLЗапроса = БазовыйURL + HTTPЗапрос.ПараметрыЗапросаСтрокой;

// Пример того, как выглядел бы URL в сообщении форума после URL-кодирования
// &masigk=%5B%221821187324101442209201989105456%22%5D

Использование объекта HTTPЗапрос с методом УстановитьПараметрыЗапроса() и последующим обращением к свойству ПараметрыЗапросаСтрокой часто автоматически обрабатывает URL-кодирование для значений параметров. Однако, если вы вручную собираете URL-строку, обязательно используйте ПроцентноеКодирование() для каждого значения параметра.

Шаг 2: Извлечение и десериализация JSON-строки на стороне HTTP-сервиса (Принимающая 1С)

На стороне HTTP-сервиса 1С мы получим параметр masigk как обычную строку. Первым делом, необходимо убедиться, что HTTP-сервис правильно декодировал URL-кодированную строку. Обычно платформа 1С делает это автоматически, предоставляя значение параметра уже в декодированном виде.

После получения строки нам нужно ее десериализовать обратно в массив. Для этого используем объекты ЧтениеJSON и функцию ПрочитатьJSON():


// Предполагаем, что "Данные.masigk" содержит декодированную JSON-строку,
// например, '["1821187324101442209201989105456", "другойИдентификатор"]'
СтрокаМассиваИзПараметра = Данные.masigk;

// Создаем объект для чтения JSON
ЧтениеМассива = Новый ЧтениеJSON;

// Устанавливаем строку, которую будем читать.
// Если в СтрокаМассиваИзПараметра есть закодированные символы (например, %20 для пробела),
// то ЧтениеJSON ожидает уже декодированную строку.
ЧтениеМассива.УстановитьСтроку(СтрокаМассиваИзПараметра);

// Прочитываем JSON и получаем из него массив.
// Параметр Истина указывает, что ожидаем прочитать корневой элемент.
МассивСтрокЦифрИГК = ПрочитатьJSON(ЧтениеМассива, Истина);

// Теперь переменная МассивСтрокЦифрИГК будет содержать объект типа "Массив",
// который можно обходить в цикле или использовать как обычный массив 1С.
Для Каждого ЭлементМассива Из МассивСтрокЦифрИГК Цикл
    // Обработка каждого элемента массива
    Сообщить(ЭлементМассива);
КонецЦикла;

Как видно из сообщений форума, этот подход оказался рабочим и позволил успешно передать и обработать массив — для такой задачи есть обмен данными между базами 1С через HTTP. Используя ЧтениеJSON и ПрочитатьJSON, мы получаем на стороне сервера полноценный объект "Массив" 1С, который можно обрабатывать стандартными средствами платформы.

Альтернативные способы передачи массивов в GET-параметрах

Хотя JSON-сериализация является гибким и мощным методом, существуют и другие подходы, которые могут быть более простыми для некоторых случаев. Рассмотрим их:

  1. Повторяющиеся ключи:

    Это один из наиболее распространенных способов, который автоматически распознается многими серверными фреймворками. Суть заключается в повторении имени параметра для каждого элемента массива, часто с добавлением пустых квадратных скобок ([]) или индексов.

    • С пустыми скобками: masigk[]=value1&masigk[]=value2&masigk[]=value3
    • С индексами: masigk[0]=value1&masigk[1]=value2&masigk[2]=value3

    Плюсы: Многие серверные языки и фреймворки (например, PHP, Python Flask/Django) автоматически собирают такие параметры в массив, что упрощает их обработку на стороне сервера.

    Минусы: Может требовать специфической реализации на стороне HTTP-сервиса 1С для парсинга, так как стандартный механизм получения параметров Данные.masigk вернет только одно из значений или скомбинирует их в одну строку. Возможно, потребуется ручной перебор всех параметров запроса по ключам, начинающимся с masigk.

    Пример формирования в 1С:

    
    МассивИГК = Новый Массив("123", "456", "789");
    СтрокаПараметровМассива = "";
    Для Каждого ЭлементМассива Из МассивИГК Цикл
        Если Не ПустаяСтрока(СтрокаПараметровМассива) Тогда
            СтрокаПараметровМассива = СтрокаПараметровМассива + "&";
        КонецЕсли;
        СтрокаПараметровМассива = СтрокаПараметровМассива + "masigk[]=" + ПроцентноеКодирование(ЭлементМассива, КодировкаURL.UTF8);
    КонецЦикла;
    // Результат: masigk[]=123&masigk[]=456&masigk[]=789
    

    Пример обработки на стороне HTTP-сервиса 1С:

    
    // Придется вручную искать параметры, начинающиеся на "masigk[]"
    МассивПолученныхЗначений = Новый Массив();
    Для Каждого ПараметрURL Из HTTPЗапрос.ПараметрыЗапроса Цикл // Если есть доступ к исходному HTTPЗапрос
        Если СтрНачинаетсяС(ПараметрURL.Ключ, "masigk[") Тогда
            МассивПолученныхЗначений.Добавить(ПараметрURL.Значение);
        КонецЕсли;
    КонецЦикла;
    // Или, если Данные - это уже обработанные параметры, нужно смотреть,
    // как 1С группирует повторяющиеся ключи (часто берет первое или последнее значение).
    // Возможно, придется получать "сырые" параметры из тела запроса или напрямую из URL.
    
  2. Значения, разделенные запятыми (или другим разделителем):

    Простейший способ — передать массив как одну строку, где значения разделены определенным символом, например, запятой.

    Пример: masigk=value1,value2,value3

    Плюсы: Чрезвычайно прост в реализации как на стороне клиента, так и на стороне сервера. Занимает меньше места в URL, чем JSON (для простых массивов).

    Минусы: Менее надежен, если сами строковые значения массива могут содержать символ-разделитель (например, если value1 это "Значение, с запятой"). Требует ручной обработки (разбиения строки) на стороне сервера. Не подходит для передачи сложных структур данных.

    Пример формирования в 1С:

    
    МассивИГК = Новый Массив("123", "456", "789");
    СтрокаМассиваРазделителем = СтрСоединить(МассивИГК, ","); // "123,456,789"
            
    // Затем URL-кодируем всю строку:
    КодированнаяСтрокаМассива = ПроцентноеКодирование(СтрокаМассиваРазделителем, КодировкаURL.UTF8);
    // Добавляем к URL: &masigk=123%2C456%2C789
    

    Пример обработки на стороне HTTP-сервиса 1С:

    
    СтрокаПараметра = Данные.masigk; // Например, "123,456,789"
    МассивПолученныхЗначений = СтрРазделить(СтрокаПараметра, ",", Ложь);
    // Теперь МассивПолученныхЗначений содержит элементы массива
    

Сравнение методов

Для случая, когда и клиент, и сервер — это 1С, JSON-сериализация является предпочтительным и наиболее надежным решением, как это подтвердила и тема форума.

Дополнительные важные аспекты

Ограничения длины URL

Метод GET имеет ограничения на длину URL. Хотя в HTTP-спецификации нет строгого лимита, браузеры и веб-серверы накладывают свои собственные ограничения. Обычно это от 2 до 8 КБ, но может достигать 16 КБ. Если ваш массив содержит очень много элементов или сами элементы очень длинные, передача его через GET-параметр в виде JSON-строки может привести к превышению этих лимитов и ошибке запроса.

Решение: В таких случаях предпочтительнее использовать HTTP-POST запрос. В POST-запросах данные передаются в теле запроса, а не в URL, что снимает ограничения на длину данных и делает его более подходящим для передачи больших объемов информации или чувствительных данных.

URL-кодирование в 1С

Как уже было упомянуто, ПроцентноеКодирование() — это функция 1С для URL-кодирования строк. Она преобразует специальные символы (например, пробелы, символы &, ?, /, =, %, квадратные скобки [ ], фигурные скобки { }, кавычки " и т.д.) в их процентные эквиваленты (например, пробел в %20, [ в %5B). Это обеспечивает корректное формирование URL, предотвращая неправильную интерпретацию параметров.

Пример использования:


СтрокаДляКодирования = "Значение с пробелами и символами [\"json\"]";
КодированнаяСтрока = ПроцентноеКодирование(СтрокаДляКодирования, КодировкаURL.UTF8);
Сообщить(КодированнаяСтрока); // Выведет что-то вроде: Значение%20с%20пробелами%20и%20символами%20%5B%22json%22%5D

Обработка ошибок

При работе с внешними сервисами или при парсинге данных всегда предусматривайте обработку ошибок. Например, если полученная строка Данные.masigk не является валидным JSON, функция ПрочитатьJSON() может вызвать исключение. Об этом важно помнить при создании надежных решений.


Попытка
    МассивСтрокЦифрИГК = ПрочитатьJSON(ЧтениеМассива, Истина);
Исключение
    Сообщить("Ошибка при десериализации JSON: " + ОписаниеОшибки());
    // Обработка ошибки, возможно, возврат кода ошибки HTTP 400 Bad Request
КонецПопытки;

Заключение

Передача одномерного массива строковых данных в параметрах HTTP-GET запроса из 1С в HTTP-сервис 1С наилучшим образом реализуется через JSON-сериализацию — для этого подойдёт универсальный обмен данными между 1С по HTTP. Этот метод обеспечивает гибкость, надежность и простоту обработки на обеих сторонах, так как платформа 1С предоставляет встроенные средства для работы с JSON. Всегда помните о необходимости URL-кодирования значений параметров и учитывайте ограничения на длину URL, при больших объемах данных отдавая предпочтение POST-запросам.

← На главную