Интеграции в 1С

Параметры POST-запроса в 1С: тело, заголовки, авторизация, форматы

Коротко

POST-запрос в 1С собирается из четырёх обязательных частей: адрес ресурса, заголовки (обязательно Content-Type, часто — Authorization), тело (JSON-строка, форма или бинарные данные) и метод отправкиВызватьHTTPМетод("POST", …) либо ОтправитьДляОбработки().

Тело задают методом УстановитьТелоИзСтроки() с кодировкой UTF-8 и ByteOrderMark = НеИспользовать — иначе многие API падают с 400 из-за трёх «мусорных» байт в начале. Для файлов используют УстановитьТелоИзДвоичныхДанных(). Ответ читается через ПолучитьТелоКакСтроку() и разбирается по КодСостояния.

Из чего состоит POST-запрос в 1С

Прежде чем разбирать параметры POST-запроса в 1С по отдельности, полезно увидеть его целиком. Минимальный рабочий POST на языке 1С:Предприятие 8.3 выглядит так:

Соединение = Новый HTTPСоединение("api.example.com", 443, , , , 30, Новый ЗащищенноеСоединениеOpenSSL());

Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Заголовки.Вставить("Accept",       "application/json");

Запрос = Новый HTTPЗапрос("/v1/orders", Заголовки);
Запрос.УстановитьТелоИзСтроки(
    "{""number"":""A-100"",""sum"":1500}",
    КодировкаТекста.UTF8,
    ИспользованиеByteOrderMark.НеИспользовать);

Ответ = Соединение.ВызватьHTTPМетод("POST", Запрос);
Сообщить("Код: " + Ответ.КодСостояния + ", тело: " + Ответ.ПолучитьТелоКакСтроку());

Здесь по шагам виден весь контракт: соединение → заголовки → HTTPЗапрос с адресом и заголовками → тело со строгой кодировкой → отправка методом POST → чтение КодСостояния и тела. Дальше по разделам разберём каждый параметр.

HTTPЗапрос и Content-Type: конструктор, адрес, заголовки

Объект HTTPЗапрос инкапсулирует всё, что уходит на сервер, кроме собственно транспорта. У конструктора две подписи:

// Пустой — заполняем поля вручную
Запрос = Новый HTTPЗапрос();
Запрос.АдресРесурса = "/v1/orders";

// Сразу с адресом и заголовками
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json");
Запрос = Новый HTTPЗапрос("/v1/orders?debug=1", Заголовки);
HTTPЗапрос
АдресРесурсапуть и query-string, без схемы и хоста
ЗаголовкиСоответствие: имя → значение
HTTPЗапрос

Важные детали параметра АдресРесурса: это относительный путь (схема и хост живут в HTTPСоединение), а параметры GET-строки нужно URL-кодировать вручную — 1С не делает этого сама. Для кодирования используйте КодироватьСтроку(Значение, СпособКодированияСтроки.КодировкаURL).

Content-Type — главный параметр заголовков

От Content-Type зависит, как сервер парсит тело. Три формата покрывают 99% API:

// 1) JSON API (самый частый вариант)
Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");

// 2) HTML-форма / OAuth token endpoint
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");

// 3) Загрузка файлов
Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=----1CBoundary7d9f");

// 4) SOAP / XML API
Заголовки.Вставить("Content-Type", "text/xml; charset=utf-8");

Ошибка «параметры POST-запроса 1С не доходят до сервера» в 90% случаев — это рассинхрон Content-Type и реального содержимого тела: заголовок application/json, а внутри key=value. Сервер вернёт 400 или молча проигнорирует поля.

Задавать Content-Length вручную не нужно — платформа считает его сама по итоговому размеру тела. Если API требует нестандартный заголовок (X-Api-Key, X-Request-Id) — просто добавьте его в тот же Соответствие.

Тело POST-запроса: JSON, form-urlencoded, multipart

Тело в application/json

Пример POST-запроса JSON в 1С: собираем данные в Структуру, сериализуем через ЗаписьJSON, кладём результат в тело методом УстановитьТелоИзСтроки().

ДанныеЗаказа = Новый Структура;
ДанныеЗаказа.Вставить("number", "A-100");
ДанныеЗаказа.Вставить("client", "ООО Ромашка");
ДанныеЗаказа.Вставить("sum",    1500.50);

Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, ДанныеЗаказа);
ТелоJSON = Запись.Закрыть();

Запрос.УстановитьТелоИзСтроки(
    ТелоJSON,
    КодировкаТекста.UTF8,
    ИспользованиеByteOrderMark.НеИспользовать);
УстановитьТелоИзСтроки
ТелоКакСтрокаготовая строка тела
КодировкаКодировкаТекста.UTF8 (по умолчанию)
ИспользоватьBOMдля API — НеИспользовать
ничего не возвращает

Критический момент. Третий параметр ИспользованиеByteOrderMark по умолчанию для UTF-8 равен Использовать. Это добавит три байта BOM (EF BB BF) в начало тела, и большинство JSON-парсеров упадёт с ошибкой «Unexpected token at position 0». Для REST API всегда явно указывайте ИспользованиеByteOrderMark.НеИспользовать.

Тело в x-www-form-urlencoded

Формат x-www-form-urlencoded используют OAuth token endpoints, старые API, формы. Пары ключ=значение склеиваются через &, значения обязательно URL-кодируются:

Пары = Новый Массив;
Пары.Добавить("grant_type=client_credentials");
Пары.Добавить("client_id="     + КодироватьСтроку("app-42",       СпособКодированияСтроки.КодировкаURL));
Пары.Добавить("client_secret=" + КодироватьСтроку("s3cr3t/пароль", СпособКодированияСтроки.КодировкаURL));
Пары.Добавить("scope="         + КодироватьСтроку("orders read",   СпособКодированияСтроки.КодировкаURL));

ТелоФормы = СтрСоединить(Пары, "&");

Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
Запрос.УстановитьТелоИзСтроки(
    ТелоФормы,
    КодировкаТекста.UTF8,
    ИспользованиеByteOrderMark.НеИспользовать);

Типичная ошибка — забыть закодировать значение с пробелами, символами &, =, + или кириллицей. Сервер разобьёт строку по & и = в неправильных местах, и параметры POST-запроса 1С придут «съехавшими».

Тело в multipart/form-data и бинарные данные

Для отправки файлов (загрузка накладной, изображения, PDF) используют multipart/form-data и метод УстановитьТелоИзДвоичныхДанных():

Файл = Новый ДвоичныеДанные("C:\Обмен\invoice.pdf");
Граница = "----1CBoundary" + Строка(Новый УникальныйИдентификатор());
CRLF = Символы.ВК + Символы.ПС;

// Пре- и постамбула multipart-части
Преамбула =
    "--" + Граница + CRLF
    + "Content-Disposition: form-data; name=""file""; filename=""invoice.pdf""" + CRLF
    + "Content-Type: application/pdf" + CRLF + CRLF;
Постамбула = CRLF + "--" + Граница + "--" + CRLF;

// Склейка через поток
Поток = Новый ПотокВПамяти;
Поток.Записать(ПолучитьДвоичныеДанныеИзСтроки(Преамбула, КодировкаТекста.UTF8, Ложь).ОткрытьПотокДляЧтения());
Поток.Записать(Файл.ОткрытьПотокДляЧтения());
Поток.Записать(ПолучитьДвоичныеДанныеИзСтроки(Постамбула, КодировкаТекста.UTF8, Ложь).ОткрытьПотокДляЧтения());

Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Граница);
Запрос.УстановитьТелоИзДвоичныхДанных(Поток.ЗакрытьИПолучитьДвоичныеДанные());
УстановитьТелоИзДвоичныхДанных
ДанныеДвоичныеДанные для тела
ничего не возвращает

Правило выбора метода: текст → УстановитьТелоИзСтроки() (кодировка и BOM управляются параметрами), файлы, бинарные протоколы, заранее собранный multipart → УстановитьТелоИзДвоичныхДанных(). Смешивать нельзя: последний вызов перезаписывает тело.

Как это в Консоли кода

В Консоли кода Aether Lab можно набросать POST одной фразой в чате — ассистент сам подставит рабочий шаблон с HTTPСоединение, JSON-сериализацией и корректным BOM, выполнит запрос в песочнице и покажет КодСостояния с телом ответа. Дальше можно попросить «переделай под Basic Auth» или «добавь загрузку файла» — и код перепишется в том же окне.

Собери мне POST-запрос в 1С к https://api.example.com/v1/orders с телом JSON {"number":"A-100","sum":1500}, авторизацией Bearer TOKEN и покажи, как разобрать ответ по КодСостояния.

Авторизация в POST-запросе: Basic, Bearer, API-Key

Заголовок Authorization — отдельная точка отказа: 90% ошибок 401 приходят из-за него. Три рабочих варианта:

// 1) Basic Auth — логин:пароль в base64
СтрокаКреды = "admin:P@ssw0rd";
Base64 = Base64Строка(ПолучитьДвоичныеДанныеИзСтроки(СтрокаКреды, КодировкаТекста.UTF8, Ложь));
// Base64Строка добавляет перевод строки — обязательно чистим:
Base64 = СтрЗаменить(СтрЗаменить(Base64, Символы.ВК, ""), Символы.ПС, "");
Заголовки.Вставить("Authorization", "Basic " + Base64);

// 2) Bearer Token (OAuth2, JWT)
Заголовки.Вставить("Authorization", "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...");

// 3) API-Key в кастомном заголовке
Заголовки.Вставить("X-Api-Key", "sk_live_9f8a7b6c5d4e3f2a1b0c");

Альтернатива Basic Auth — передать логин и пароль напрямую в HTTPСоединение: третий и четвёртый параметры конструктора. 1С сама сформирует корректный заголовок Authorization: Basic …, и вручную ничего кодировать не придётся:

Соединение = Новый HTTPСоединение("api.example.com", 443, "admin", "P@ssw0rd", , 30, Новый ЗащищенноеСоединениеOpenSSL());

Для Bearer и API-Key такого сокращения нет — только через заголовки. Не храните токены в коде обработки: используйте параметры сеанса, безопасное хранилище или справочник констант с шифрованием.

Отправка: ВызватьHTTPМетод vs ОтправитьДляОбработки

В 1С есть два метода HTTPСоединение, которые физически отправляют POST:

// Универсальный способ — работает для любого метода
Ответ = Соединение.ВызватьHTTPМетод("POST", Запрос);

// Устаревший shortcut только для POST — оставлен для совместимости
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
ВызватьHTTPМетод
HTTPМетод"POST", "PUT", "PATCH", "DELETE"
HTTPЗапросподготовленный HTTPЗапрос
ИмяВыходногоФайлатело ответа сразу в файл
HTTPОтвет

Рекомендация: используйте ВызватьHTTPМетод("POST", …) — это универсальный API, который единообразно работает и для POST, и для PUT, и для DELETE, и его проще рефакторить. ОтправитьДляОбработки() оставили для обратной совместимости.

Разбор ответа: КодСостояния, тело, JSON

Ответ на POST в 1С — это объект HTTPОтвет с полями КодСостояния, Заголовки и методами получения тела:

Ответ = Соединение.ВызватьHTTPМетод("POST", Запрос);

Если Ответ.КодСостояния = 200 ИЛИ Ответ.КодСостояния = 201 Тогда
    ТелоОтвета = Ответ.ПолучитьТелоКакСтроку();
    Чтение = Новый ЧтениеJSON;
    Чтение.УстановитьСтроку(ТелоОтвета);
    ДанныеОтвета = ПрочитатьJSON(Чтение);
    Сообщить("ID заказа: " + ДанныеОтвета["order_id"]);

ИначеЕсли Ответ.КодСостояния = 401 Тогда
    ВызватьИсключение "Ошибка авторизации: проверьте токен/Basic Auth";

ИначеЕсли Ответ.КодСостояния = 400 Тогда
    ВызватьИсключение "Некорректное тело запроса: " + Ответ.ПолучитьТелоКакСтроку();

Иначе
    ВызватьИсключение "HTTP " + Ответ.КодСостояния + ": " + Ответ.ПолучитьТелоКакСтроку();
КонецЕсли;

Метод ПолучитьТелоКакСтроку() у HTTPОтвет принимает необязательный параметр Кодировка: если сервер вернул ответ не в UTF-8, а, например, в windows-1251, укажите её явно, иначе получите «кракозябры».

Частые ошибки в параметрах POST-запроса в 1С

  • BOM в начале тела. Не указали ИспользованиеByteOrderMark.НеИспользовать — JSON-API падает с 400 «Unexpected token». Всегда передавайте третий параметр УстановитьТелоИзСтроки().
  • Content-Type не совпадает с телом. Заголовок application/json, а внутри key=value&key2=value2 — сервер вернёт 400 или проигнорирует поля.
  • Русские символы без URL-кодирования. В x-www-form-urlencoded и в query-string кириллицу и спецсимволы обязательно пропускайте через КодироватьСтроку(…, СпособКодированияСтроки.КодировкаURL).
  • Лишний перевод строки в Base64Строке. Base64Строка() добавляет \r\n. Для заголовка Authorization: Basic … его нужно вручную удалить, иначе сервер вернёт 401.
  • HTTP вместо HTTPS без ЗащищенноеСоединениеOpenSSL. Если API работает по TLS, у HTTPСоединение обязателен последний параметр Новый ЗащищенноеСоединениеOpenSSL(), иначе 1С попытается открыть обычный http и получит ошибку.
  • Игнорирование КодСостояния. 1С не бросает исключение при 4xx/5xx — она просто возвращает HTTPОтвет. Проверять КодСостояния нужно всегда, иначе ошибочный ответ проскочит как «успешный».
  • Один HTTPСоединение на десятки запросов без Таймаут. Без явного таймаута зависшая сессия блокирует фоновое задание. Указывайте таймаут в секундах шестым параметром конструктора HTTPСоединение.
Как это в Консоли кода

Если POST в 1С возвращает 400 или 401, а причина непонятна — вставьте код в Консоль кода Aether Lab и попросите разобрать ошибку. Ассистент прогонит запрос в песочнице, покажет реальные заголовки и тело, которые ушли на сервер, и подскажет, что именно API не принял: BOM, Content-Type, кодировку или подпись Bearer-токена.

Мой POST-запрос в 1С возвращает 400 — покажи, какое тело реально уходит на сервер, и что в параметрах Content-Type/кодировке нужно исправить.

Чек-лист параметров POST-запроса перед отправкой

  • Адрес — относительный путь, query-string URL-кодирован.
  • Content-Type — совпадает с реальным телом (JSON / form / multipart).
  • Тело — сериализовано корректно (Структура→ЗаписьJSON для JSON, СтрСоединить для form).
  • Кодировка — UTF-8, ByteOrderMark = НеИспользовать.
  • Authorization — Basic без переносов строк, Bearer с префиксом «Bearer», API-Key в кастомном заголовке.
  • HTTPS — конструктор HTTPСоединение с ЗащищенноеСоединениеOpenSSL и таймаутом.
  • Разбор ответа — проверка КодСостояния до чтения тела, отдельная ветка для 401/400/5xx.

Частые вопросы про POST-запрос в 1С

Как передать JSON в POST-запросе 1С без ошибки 400?

Соберите строку JSON через ЗаписьJSON, поставьте Content-Type: application/json; charset=utf-8 и вызовите УстановитьТелоИзСтроки(Тело, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать). Именно последний параметр (без BOM) чаще всего и лечит 400 на JSON-API.

Как добавить авторизацию Bearer к POST-запросу в 1С?

Добавьте в Соответствие заголовков пару "Authorization""Bearer " + Токен и передайте соответствие вторым параметром конструктора HTTPЗапрос. Для Basic Auth удобнее передать логин и пароль третьим и четвёртым параметрами HTTPСоединение — заголовок 1С сформирует сама.

Чем УстановитьТелоИзСтроки отличается от УстановитьТелоИзДвоичныхДанных?

УстановитьТелоИзСтроки() принимает готовую строку и управляет кодировкой и BOM — используйте для JSON, XML, form-urlencoded. УстановитьТелоИзДвоичныхДанных() кладёт в тело ДвоичныеДанные «как есть» — используйте для файлов, готовых multipart-конструкций и бинарных протоколов.