При интеграции 1С с внешними системами, такими как GitLab, разработчики часто сталкиваются с необходимостью повторить логику работы готовых скриптов на curl. Одной из неочевидных задач является одновременная передача параметров --data и --data-urlencode. В этой статье мы разберем, как работает механика объединения данных в HTTP-протоколе, как правильно сформировать тело запроса в 1С и решим сопутствующие проблемы с авторизацией и отображением полученного контента.
Для начала проанализируем, что происходит "под капотом" у curl, когда мы указываем несколько флагов передачи данных. Важно понимать, что в стандартном HTTP-запросе тело (body) является единым потоком данных. Согласно официальной документации curl, параметры --data, --data-binary и --data-urlencode не создают разные типы данных в одном запросе. Вместо этого они склеиваются в одну строку через символ амперсанда &.
Разница заключается лишь в предварительной обработке:
--data — передает строку «как есть». Предполагается, что спецсимволы в ней уже закодированы вами вручную.--data-urlencode — заставляет curl самостоятельно выполнить URL-кодирование (экранирование) спецсимволов перед отправкой.Таким образом, для 1С это означает одну простую вещь: нам нужно собрать единую строку тела запроса, где каждая часть подготовлена соответствующим образом. Рассмотрим, как это реализовать программно.
Выясним причину, по которой сервер может отвергать запрос. Чаще всего это неправильный заголовок Content-Type. Для имитации формы авторизации (которую и делает curl с этими флагами), необходимо использовать application/x-www-form-urlencoded. В этом случае все данные передаются как пары "ключ=значение".
Проанализируем пример формирования параметров в 1С. Допустим, нам нужно передать логин, пароль и токен безопасности (CSRF-токен), полученный из предыдущего запроса. Токен часто содержит спецсимволы (плюсы, слеши, равно), которые сломают структуру запроса, если их не закодировать.
Посмотрим на пример кода для подготовки строки тела:
// Определяем значения
Логин = "gitlab_user";
Пароль = "super_password#123"; // Символ # требует кодирования
Токен = "dG9rZW4rZGF0YQ=="; // Пример токена с символами + и =
// Кодируем параметры, которые могут содержать спецсимволы
// Используем URLУмеренное для сохранения структуры ключей
ЗакодированныйПароль = КодироватьСтроку(Пароль, СпособКодированияСтроки.URLУмеренное);
ЗакодированныйТокен = КодироватьСтроку(Токен, СпособКодированияСтроки.URLУмеренное);
// Собираем итоговое тело запроса (аналог склейки в curl)
ТелоЗапроса = "user[login]=" + Логин +
"&user[password]=" + ЗакодированныйПароль +
"&authenticity_token=" + ЗакодированныйТокен;
Рассмотрим подробнее процесс отправки. Нам потребуется объект HTTPЗапрос. Важно помнить, что если вы используете LDAP-авторизацию, сервер ожидает не только тело, но и куки (cookies), полученные при первом обращении к странице логина.
// Создаем соединение
НТТРСоединение = Новый HTTPСоединение("gitlab.example.com", , , , , , Новый ЗащищенноеСоединениеOpenSSL());
// Создаем запрос
Запрос = Новый HTTPЗапрос("/users/sign_in");
// Устанавливаем обязательный заголовок
Запрос.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
// Если у нас есть куки из предыдущего GET-запроса, добавляем их
// Куки обычно передаются в заголовке "Cookie"
Запрос.Заголовки.Вставить("Cookie", "session_id=...; _gitlab_session=...");
// Устанавливаем сформированное тело
Запрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8);
// Отправляем POST-запрос
Ответ = НТТРСоединение.ОтправитьДляОбработки(Запрос);
Обратите внимание на вопрос о Base64, который часто возникает у разработчиков (сообщение 1 темы). При использовании стандартных веб-форм Base64 не применяется для полей логина и пароля. Данные передаются в открытом (но URL-закодированном) виде. Безопасность обеспечивается самим протоколом HTTPS, который шифрует весь трафик.
Проанализируем ситуацию: для успешного входа в GitLab через веб-интерфейс (не API) недостаточно одного запроса. Нужно выполнить цепочку действий, которую автор темы успешно реализовал в сообщении 14:
/users/sign_in. Из заголовков ответа (Set-Cookie) сохраняем сессионные куки. Из тела ответа (HTML) извлекаем значение скрытого поля authenticity_token.Часто после успешного получения HTML-кода страницы при помощи ПолучитьТелоКакСтроку(), разработчики сталкиваются с тем, что в поле HTML-документа на форме 1С страница "разваливается": пропадают стили, картинки и скрипты (сообщение 14). Выясним причину: это происходит из-за относительных путей в коде GitLab.
В HTML коде ссылки на стили выглядят как /assets/application.css. Поле HTML-документа 1С пытается найти их на локальном диске или по адресу, который ему неизвестен. Чтобы это исправить, выполним одно из следующих действий:
<head> полученного HTML-текста нужно программно вставить тег <base href="https://your-gitlab-host.com/">. Это заставит встроенный браузер искать все относительные ресурсы по правильному адресу.src="/ на src="https://your-gitlab-host.com/ и аналогично для href.Пример программной правки HTML перед выводом на форму:
ТекстHTML = Ответ.ПолучитьТелоКакСтроку();
// Вставляем базовый URL для корректной загрузки стилей и скриптов
ТекстHTML = СтрЗаменить(ТекстHTML, "<head>", "<head><base href=""https://gitlab.mycompany.ru/"">");
Элементы.ПолеHTMLПросмотра.УстановитьТекст(ТекстHTML);
Таким образом, мы разобрали, что "совмещение" разных параметров данных в 1С сводится к правильной конкатенации строки и ручному URL-кодированию чувствительных частей данных. Этот подход универсален и применим не только к GitLab, но и к любым веб-сервисам, требующим авторизации через формы.