После обновления платформы 1С:Предприятие на версию 8.3.17, 8.3.18 или более свежие релизы разработчики часто сталкиваются с неприятным сюрпризом: HTTP-запросы, которые годами работали стабильно, внезапно начинают возвращать ошибки. При детальном анализе отправляемых пакетов выясняется, что платформа автоматически заменяет все символы обратного слэша \ на прямой слэш / в адресе ресурса.
В этой статье мы подробно разберем, почему изменилось поведение платформы, как это связано с международными стандартами и какими способами можно обойти данное ограничение, чтобы восстановить работоспособность интеграции с внешними сервисами.
Начиная с версии платформы 1С 8.3.17, разработчики переписали и ужесточили механизмы работы с сетевыми функциями. В частности, внутренний парсер адресов (URI) был приведен в строгое соответствие с международным стандартом RFC 3986 (стандарт описания веб-адресов).
Проанализируем ключевые моменты этого изменения:
\ является недопустимым символом в строке URI. Его использование в «сыром» виде нарушает правила сетевого обмена./.\\ в строке кода 1С) не приводят к успеху. Платформа все равно обнаруживает запрещенный символ и превращает его либо в одиночный, либо в двойной прямой слэш / или //.С этой проблемой часто сталкиваются при интеграции со спутниковой системой мониторинга Wialon (Виалон) или другими веб-сервисами, которые требуют передавать сложные JSON-структуры прямо внутри параметров GET-запроса (в строке URL).
Рассмотрим конкретную ситуацию, с которой столкнулся автор темы на форуме. При отправке запроса к API Wialon требовалось передать параметры конфигурации датчика в виде JSON-строки. В документации сервиса было указано, что ключи и значения внутри JSON должны быть экранированы слэшами:
"{\"appear_in_popup\":true,\"show_time\":false}"
Однако, как показывает практика реальной разработки и официальные ответы технической поддержки сервиса, такое экранирование часто является избыточным. Большинство современных веб-серверов отлично разбирают стандартный JSON-объект без лишних обратных слэшей перед кавычками.
Если мы уберем экранирование, строка примет стандартный вид:
СтрокаКонфигурацииДатчика = "{" + """" + "appear_in_popup" + """" + ":true," + """" + "show_time" + """" + ":false}";
Или, используя более лаконичное написание с кавычками внутри строки:
СтрокаКонфигурацииДатчика = "{""appear_in_popup"":true,""show_time"":false}";
Проанализировав этот вариант, мы избавимся от использования запрещенного символа \ в коде. Платформе 1С больше нечего будет заменять на прямой слэш, и запрос успешно выполнится.
Что делать, если внешняя система принципиально требует передачи символа обратного слэша или других спецсимволов (фигурные скобки, кавычки, пробелы) внутри GET-параметра? В этом случае нам поможет стандартный механизм процентного кодирования (также известного как URL-Encoding).
При использовании этого метода все опасные и запрещенные символы заменяются на безопасные последовательности вида %XX, где XX — шестнадцатеричный код символа в таблице ASCII. Для обратного слэша \ такой последовательностью является %5C, для фигурной скобки { — %7B, а для кавычки — %22.
Разберем по шагам, как правильно выполнить URL-кодирование в 1С с помощью встроенной функции КодироватьСтроку:
// Наш исходный адрес запроса и «сырые» параметры датчика
ИмяХоста = "api.wialon.com";
НазваниеКоманды = "wialon/ajax.html?svc=unit/update_sensor";
СтрокаКонфигурацииДатчика = "{\""appear_in_popup\"":true,\"show_time\":false}";
// ВАЖНО: Кодируем только само значение параметра, а не весь URL целиком!
// Иначе служебные символы "?" и "=" также будут закодированы, и сервер не поймет запрос.
ЗакодированныеПараметры = КодироватьСтроку(СтрокаКонфигурацииДатчика, СпособКодированияСтроки.КодировкаURL);
// Собираем полный адрес ресурса
АдресРесурса = НазваниеКоманды + "¶ms=" + ЗакодированныеПараметры;
HTTPЗапрос = Новый HTTPЗапрос;
HTTPЗапрос.АдресРесурса = АдресРесурса;
HTTPЗапрос.Заголовки.Вставить("Content-type", "application/x-www-form-urlencoded");
// Выполняем запрос
ssl = Новый ЗащищенноеСоединениеOpenSSL();
HTTPСоединение = Новый HTTPСоединение(ИмяХоста, , , , , , ssl);
Ответ = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
При таком подходе платформа 1С увидит в адресе ресурса только разрешенные символы (буквы, цифры и знак процента %), поэтому автоматическая нормализация слэшей не сработает. Принимающий веб-сервер при обработке запроса автоматически раскодирует последовательность %5C обратно в символ \.
Передача сложных JSON-структур, xml-данных или длинных параметров внутри строки адреса (GET-параметры) считается плохим тоном в веб-разработке. Длина URL-строки в ряде систем ограничена (например, лимит может составлять от 2048 до 8192 символов).
Если целевой веб-сервис поддерживает работу с методами POST или PUT, настоятельно рекомендуется передавать все структурированные данные внутри тела запроса. Данные в теле передаются «как есть» (в бинарном или текстовом виде) напрямую в потоке сетевого соединения. Платформа 1С никак не валидирует и не нормализует содержимое тела запроса, поэтому любые спецсимволы, включая обратные слэши, сохранят свой первозданный вид.
Посмотрим на пример реализации отправки данных в теле HTTP-запроса:
// В адресе ресурса оставляем только путь к методу API
HTTPЗапрос = Новый HTTPЗапрос;
HTTPЗапрос.АдресРесурса = "wialon/ajax.html?svc=unit/update_sensor";
// Задаем заголовки, сообщающие серверу о формате передаваемых данных
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
// Исходная строка с обратными слэшами
СтрокаКонфигурацииДатчика = "{\""appear_in_popup\"":true,\"show_time\":false}";
// Устанавливаем строку напрямую в тело запроса
HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаКонфигурацииДатчика, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
// Отправляем POST-запрос
ssl = Новый ЗащищенноеСоединениеOpenSSL();
HTTPСоединение = Новый HTTPСоединение(ИмяХоста, , , , , , ssl);
Ответ = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Использование тела запроса полностью решает проблемы с кодированием, спецсимволами, длиной параметров и делает интеграцию гораздо более надежной и масштабируемой.
Аналогичная проблема после обновления платформы возникает и при передаче текстовых сообщений, содержащих управляющий символ переноса строки \n. При парсинге URL-адреса последовательность \n преобразуется платформой 1С в /n, из-за чего на стороне получателя текст слипается в одну строчку.
Для решения этой проблемы мы можем использовать один из двух проверенных способов:
"\n", используйте предопределенный символ платформы Символы.ПС (перевод строки). Например:
ТекстСообщения = "Первая строка" + Символы.ПС + "Вторая строка";
При отправке в теле запроса платформа корректно передаст этот символ принимающей стороне.
КодироватьСтроку. Символ переноса строки превратится в последовательность %0A (или %0D%0A для связки ВозвратКаретки+ПереводСтроки), которая безболезненно пройдет парсер 1С и будет правильно интерпретирована веб-сервером.
Мы проанализировали причины изменения поведения платформы 1С при работе с HTTP-соединениями и рассмотрели практические варианты исправления ошибок. Рекомендуем своевременно проводить аудит кода интеграций при планировании обновлений платформы 1С:Предприятие.