Почему 1С не видит параметры в HTTP-запросе из мобильного приложения и как это исправить

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

При разработке систем интеграции между мобильными приложениями на Android и HTTP-сервисами 1С программисты часто сталкиваются с ситуацией, когда запросы, прекрасно работающие в браузере или на новых версиях Android, «теряют» часть данных на старых устройствах (Android 6 и ниже). В этой статье мы подробно разберем, почему пропадают параметры запроса, как влияет кодировка URL на стабильность связи и как правильно перевести обмен данными на метод POST для обеспечения максимальной надежности.

Анализ проблемы: почему исчезают параметры GET-запроса

Рассмотрим стандартную ситуацию: мобильное приложение отправляет GET-запрос к базе 1С для авторизации пользователя. В строке запроса передаются логин и пароль. На современных устройствах всё работает корректно, однако на версиях Android 6 и ниже второй параметр (например, &pass=...) может попросту не доходить до 1С. Проанализируем типичный код формирования запроса на стороне Android:


URL url = new URL(String.format("http://server/base/hs/auth/v1?login=%s&pass=%s", login, pass));
HttpURLConnection connection = (HttpURLConnection) url.openConnection();

Основная причина проблемы кроется в некорректном экранировании спецсимволов в URL. Символы пробела, точки, кириллица или знаки препинания в логине или пароле разрывают структуру URI. В старых версиях Android механизмы автоматического кодирования строк работают менее гибко, чем в современных браузерах. Например, если в логине присутствует пробел (например, "Иванов И.И."), и он не был преобразован в %20, сервер (IIS или Apache) может воспринять это как конец заголовка запроса или некорректный путь, обрезая всё, что идет после пробела.

Выясним еще одну важную деталь: 1С воспринимает объект Запрос как уже разобранный URI. Если структура строки нарушена на этапе передачи, коллекция Запрос.ПараметрыЗапроса будет содержать только те элементы, которые удалось распознать до первого «критичного» символа.

Решение №1: Использование правильного URL-кодирования

Первым шагом в исправлении ситуации должно стать принудительное кодирование всех строковых параметров, передаваемых в GET-запросе. В 1С для этих целей можно использовать MSScriptControl (если работа идет на Windows-сервере) или встроенные средства платформы для работы со строками. Однако правильнее всего обрабатывать это на стороне отправителя (Android).

Вместо прямой склейки строк в Android следует использовать URLEncoder.encode(string, "UTF-8"). Это преобразует "Иванов И.И." в " %D0%98%D0%B2%D0%B0%D0%BD%D0%BE%D0%B2%20%D0%98.%D0%98.". Рассмотрим, как это влияет на стабильность:

Если же параметры содержат сложные данные (например, длинные описания задач), GET-запрос может столкнуться с ограничением по длине строки (обычно около 2048 символов), что также приведет к обрезке данных.

Решение №2: Переход на использование Base64

Если изменение логики приложения затруднено, можно применить промежуточное решение — кодирование всей строки параметров или отдельных значений в Base64. Это гарантирует, что в URL будут передаваться только «безопасные» символы латинского алфавита и цифры.

Проанализируем пример на стороне 1С для расшифровки таких данных:


Функция ПолучитьПараметрыИзBase64(ЗначениеBase64)
    ДвоичныеДанные = ИзBase64Строки(ЗначениеBase64);
    СтрокаПараметров = ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанные, КодировкаТекста.UTF8);
    Возврат СтрокаПараметров;
КонецФункции

Важное ограничение: Кодирование Base64 увеличивает объем передаваемых данных примерно на 33%. На старых устройствах Android при передаче больших текстов это может привести к превышению лимита длины URL еще быстрее, чем при обычном тексте.

Решение №3: Реализация метода POST (Рекомендуемый способ)

Самым надежным и профессиональным способом решения проблемы является использование метода POST вместо GET. При использовании POST данные передаются не в заголовке (URL), а в теле запроса. Это снимает ограничения на длину и избавляет от проблем с интерпретацией спецсимволов веб-сервером.

Разберем реализацию POST-запроса на Android:


static String sendPostData(String dataToPost) {
    try {
        URL url = new URL("http://your-1c-server/hs/myservice/auth");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");

        OutputStream os = conn.getOutputStream();
        os.write(dataToPost.getBytes("UTF-8"));
        os.flush();
        os.close();

        // Чтение ответа...
    } catch (Exception e) {
        return "Error: " + e.getMessage();
    }
}

Теперь проанализируем, как правильно принять эти данные в 1С. Обратите внимание: при использовании метода POST параметры больше не будут доступны в коллекции Запрос.ПараметрыЗапроса. Их нужно извлекать из тела запроса.


Функция ОсновнойPOST(Запрос)
    
    // Получаем данные из тела запроса
    ДанныеСтрокой = Запрос.ПолучитьТелоКакСтроку("UTF-8");
    
    // Если мы передавали JSON, то десериализуем его
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(ДанныеСтрокой);
    СтруктураДанных = ПрочитатьJSON(ЧтениеJSON);
    ЧтениеJSON.Закрыть();
    
    Логин = СтруктураДанных.login;
    Пароль = СтруктураДанных.pass;
    
    // Выполняем логику...
    Результат = Авторизация(Логин, Пароль);
    
    Ответ = Новый HTTPСервисОтвет(200);
    Ответ.УстановитьТелоИзСтроки(Результат);
    Возврат Ответ;
    
КонецФункции

Типичные ошибки при переходе на POST

Рассмотрим ситуации, когда даже после перехода на POST данные в 1С «не видны»:

  1. Несоответствие Content-Type: Если в Android указано application/json, а отправляется строка вида login=admin&pass=123, 1С может не считать тело корректно или возникнет ошибка парсинга. Убедитесь, что формат отправляемых данных соответствует заголовку.
  2. Кодировка: Всегда явно указывайте UTF-8 как при отправке из мобильного приложения, так и при чтении в методе Запрос.ПолучитьТелоКакСтроку("UTF-8").
  3. Попытка найти данные в параметрах: Помните, что Запрос.ПараметрыЗапроса в 1С работает только для данных, идущих после знака ? в URL. Тело POST-запроса — это отдельный поток данных.

Советы по отладке HTTP-сервисов в 1С

Чтобы точно понять, что именно приходит от мобильного устройства, воспользуйтесь записью «сырых» данных в журнал регистрации. Это поможет выяснить, на каком этапе происходит искажение — в Android-коде или уже внутри 1С.

Добавьте следующий код в начало вашей функции в 1С:


ЗаписьЖурналаРегистрации("HTTP.Debug", 
    УровеньЖурналаРегистрации.Информация, , , 
    "Тело: " + Запрос.ПолучитьТелоКакСтроку() + 
    "; Параметры: " + Запрос.ПараметрыURL.Получить("ИмяМетода"));

Посмотрим на результат в Журнале регистрации: если в теле пусто, значит проблема на стороне Android-приложения (неправильно открыт OutputStream). Если данные есть, но они «битые», проверьте кодировку и использование URLEncoder.

Использование связки POST + JSON + UTF-8 является «золотым стандартом» мобильной разработки и гарантирует, что ваше приложение будет стабильно работать на любой версии Android, независимо от сложности передаваемых данных и наличия спецсимволов в логинах или задачах.

← На главную