При интеграции 1С с внешними системами через HTTP-протокол разработчики часто сталкиваются с тем, что данные, отправленные в теле POST-запроса, доходят до сервера в искаженном виде. Типичный пример — символ «+» (плюс), который внезапно превращается в обычный пробел. Это критично, если плюс является частью пароля, токена доступа или закодированной строки. В данной статье мы подробно разберем, почему это происходит и как правильно подготовить тело запроса, чтобы данные оставались неизменными.
Для начала проанализируем ситуацию. Большинство POST-запросов используют стандарт кодирования application/x-www-form-urlencoded. Согласно спецификациям этого стандарта (в частности, RFC 1866), символ плюса является зарезервированным и служит для обозначения пробела. Когда серверная часть получает такой запрос, она автоматически выполняет декодирование (URL-decode), заменяя все плюсы на пробелы.
Следовательно, если нам нужно передать именно математический символ «+», мы должны «объяснить» это серверу, заменив его на соответствующий шестнадцатеричный код — %2B. Если этого не сделать, данные будут искажены еще до того, как программная логика сервера начнет их обрабатывать.
Если ваша задача ограничена передачей простых параметров и вы точно знаете, что проблема только в плюсе, можно воспользоваться методом СтрЗаменить. Рассмотрим пример формирования тела запроса:
ПараметрПароль = "Pass+Word";
Тело = "donotcache=" + Формат(ТекущаяДата(), "ДФ=yyyyMMddHHmmss") +
"&password=" + ПараметрПароль;
// Выполняем ручную замену плюса на его URL-код
Тело = СтрЗаменить(Тело, "+", "%2B");
Запрос = Новый HTTPЗапрос(Ресурс);
Запрос.УстановитьТелоИзСтроки(Тело);
Результат = Соединение.ОтправитьДляОбработки(Запрос);
Важный нюанс: Этот метод называют «костылем», так как он решает проблему точечно. Если в пароле встретится символ амперсанда & или знака равенства =, этот способ не поможет, и структура запроса снова нарушится. Амперсанд будет воспринят сервером как разделитель нового параметра.
Чтобы решение было надежным и универсальным, мы должны использовать штатные механизмы платформы 1С для URL-кодирования. Функция КодироватьСтроку позволяет преобразовать любые спецсимволы, кириллицу и знаки пунктуации в формат, безопасный для HTTP-передачи.
Разберем по шагам, как это сделать правильно. Внимание: нельзя кодировать всю готовую строку тела запроса целиком! Если вы закодируете строку "param=value&key=val", то символы = и & также превратятся в коды (например, %3D и %26), и сервер не сможет разобрать ваш запрос на пары «ключ-значение».
Правильный алгоритм действий:
Посмотрим на пример кода:
Функция ПодготовитьТелоЗапроса(ПараметрыСтруктура)
Результат = "";
Для Каждого ТекущийПараметр Из ПараметрыСтруктура Цикл
Имя = ТекущийПараметр.Ключ;
// Кодируем только значение
Значение = КодироватьСтроку(Строка(ТекущийПараметр.Значение), СпособКодированияСтроки.URLУпрощенный);
Результат = Результат + ?(ПустаяСтрока(Результат), "", "&") + Имя + "=" + Значение;
КонецЦикла;
Возврат Результат;
КонецФункции
// Использование:
Данные = Новый Структура;
Данные.Вставить("donotcache", Формат(ТекущаяДата(), "ДФ=yyyyMMddHHmmss"));
Данные.Вставить("password", "My+Super&Password");
ТелоЗапроса = ПодготовитьТелоЗапроса(Данные);
// На выходе получим: donotcache=20231027...&password=My%2BSuper%26Password
В 1С:Предприятие 8.3 при вызове КодироватьСтроку можно указать второй параметр — тип кодирования. Выясним разницу:
СпособКодированияСтроки.URL — кодирует практически все символы, не входящие в латинский алфавит.СпособКодированияСтроки.URLУпрощенный — оставляет без изменений некоторые символы (например, точку, дефис), что чаще всего требуется для совместимости с веб-серверами при передаче параметров форм.Для передачи плюса как %2B подходят оба варианта, но URLУпрощенный генерирует более читаемые строки для стандартных веб-сервисов.
Если вы проектируете систему с нуля или имеете возможность изменить принимающую сторону, проанализируем современный стандарт передачи данных — JSON. В отличие от x-www-form-urlencoded, в JSON-объекте данные передаются внутри кавычек, и никаких специальных преобразований для плюса не требуется (кроме экранирования самих кавычек и обратных слэшей).
Пример использования JSON в 1С:
ДанныеДляОтправки = Новый Структура;
ДанныеДляОтправки.Вставить("password", "My+Password");
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеДляОтправки);
СтрокаТела = ЗаписьJSON.Закрыть();
Запрос = Новый HTTPЗапрос(Ресурс);
// Обязательно указываем правильный тип контента
Запрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Запрос.УстановитьТелоИзСтроки(СтрокаТела);
Этот способ избавляет от путаницы с кодированием URL-параметров и является предпочтительным в современной веб-разработке.
Если проблема сохраняется, выполним проверку через инструменты перехвата трафика, такие как Fiddler или Charles.
%2B, значит, 1С работает корректно, и проблему нужно искать в настройках или коде веб-сервера.Использование правильных методов кодирования строк в 1С гарантирует стабильную работу ваших интеграций и исключает потерю важных данных при передаче через HTTP.