Интеграция 1С с интернет-магазинами на базе CS-Cart часто требует использования их REST API. Одной из распространенных трудностей является перенос готовых команд curl, успешно работающих в Linux, в программный код 1С. Особенно много вопросов вызывает параметр --data-binary, который отвечает за передачу данных в "сыром" виде без какой-либо дополнительной обработки.
В этой статье мы подробно разберем, как правильно сформировать HTTP-запрос в 1С, чтобы он полностью соответствовал поведению curl, и разберем типичные ошибки, связанные с кодировками, заголовками и особенностями операционной системы Windows.
Рассмотрим исходную команду curl, которую необходимо перенести в 1С:
curl --header "Authorization: Basic API_TOKEN" --header 'Content-Type: application/json' -X POST --data-binary '{"stocks": {"product_code": "1", "amount": "10"}}'
Проанализируем ситуацию: в среде Linux этот запрос выполняется корректно, но при попытке запустить его через КомандаСистемы в Windows или реализовать через объекты 1С возникают ошибки. Основные причины здесь кроются в следующем:
--data-binary в curl отправляет данные ровно в том виде, в котором они представлены, не удаляя символы переноса строк и не обрабатывая спецсимволы.Basic авторизации, где токен — это не просто строка, а закодированная пара логина и API-ключа.Для начала нам необходимо подготовить объект HTTPЗапрос. Важно помнить, что для CS-Cart стандартная Basic авторизация строится по принципу: логин_администратора:api_ключ. Эту строку нужно перевести в формат Base64.
Рассмотрим, как это реализовать в коде 1С:
// Логин и ключ можно получить в панели администратора CS-Cart
Логин = "admin@example.com";
APIКлюч = "ваш_ключ_api";
// Формируем строку авторизации
СтрокаАвторизации = Логин + ":" + APIКлюч;
ДанныеАвторизации = Base64Строка(ДвоичныеДанныеИзСтроки(СтрокаАвторизации, КодировкаТекста.UTF8));
Запрос = Новый HTTPЗапрос;
Запрос.Заголовки.Вставить("Authorization", "Basic " + ДанныеАвторизации);
Запрос.Заголовки.Вставить("Content-Type", "application/json");
Запрос.Заголовки.Вставить("Accept", "application/json"); // Рекомендуется для получения ответов в JSON
Основная сложность у автора вопроса возникла с передачей данных. В 1С наиболее надежным способом имитации --data-binary является использование метода УстановитьТелоИзСтроки с обязательным указанием кодировки и отключением BOM (Byte Order Mark).
Выясним причину: веб-серверы на PHP (на которых работает CS-Cart) крайне чувствительны к невидимым символам в начале JSON-пакета. Если 1С добавит BOM-символы при сохранении в UTF-8, сервер вернет ошибку "неправильный формат медиа" или 400 Bad Request.
Разберем правильный подход:
// Формируем структуру данных
ДанныеОстатков = Новый Структура;
ДанныеОстатков.Вставить("product_code", "1");
ДанныеОстатков.Вставить("amount", "10");
ТелоЗапроса = Новый Структура;
ТелоЗапроса.Вставить("stocks", ДанныеОстатков);
// Преобразуем в JSON строку
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ТелоЗапроса);
СтрокаJSON = ЗаписьJSON.Закрыть();
// Устанавливаем тело запроса ПРАВИЛЬНО (аналог --data-binary)
// Используем КодировкаТекста.UTF8 и ИспользованиеByteOrderMark.НеИспользовать
Запрос.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Теперь проанализируем ситуацию с методом запроса. В примере автора используется POST. Однако стоит учитывать, что для обновления существующих данных (например, остатков) API CS-Cart часто ожидает метод PUT. Если POST возвращает ошибку, попробуйте сменить метод.
// Настройка соединения
Сервер = "ваш-сайт.рф";
НТТРСоединение = Новый HTTPСоединение(Сервер, 443, , , , , Новый ЗащищенноеСоединениеOpenSSL());
Попытка
// Выполняем запрос (замените "api/2.0/products/1" на ваш эндпоинт)
Ответ = НТТРСоединение.ВызватьHTTPМетод("POST", Запрос);
Сообщить("Код состояния: " + Ответ.КодСостояния);
Сообщить("Ответ сервера: " + Ответ.ПолучитьТелоКакСтроку());
Исключение
Сообщить("Ошибка при выполнении запроса: " + ОписаниеОшибки());
КонецПопытки;
Если вы все же хотите пойти по пути формирования "чистых" двоичных данных (как предлагалось в сообщении №7 форума), это можно сделать без сохранения в промежуточный файл. Рассмотрим этот вариант:
// Получаем строку JSON
СтрокаJSON = "{""stocks"": {""product_code"": ""1"", ""amount"": ""10""}}";
// Преобразуем строку в двоичные данные UTF-8 без BOM
ДвоичныеДанныеТела = ДвоичныеДанныеИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, Ложь);
// Передаем как бинарные данные
Запрос.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеТела);
Этот способ является максимально близким к логике --data-binary, так как вы полностью контролируете каждый байт, отправляемый в сокет.
Как правильно посоветовали в сообщении №9, если запрос не проходит из 1С, используйте Postman. Это позволит вам изолировать проблему:
curl в Postman через кнопку Import -> Raw text.Важный момент: Обратите внимание на заголовки Content-Length. 1С вычисляет их автоматически при использовании УстановитьТелоИзСтроки, но если вы вручную манипулируете заголовками, убедитесь, что длина указана верно (в байтах, а не в символах).
Для успешной замены curl --data-binary в 1С при работе с CS-Cart API придерживайтесь следующих правил:
ИспользованиеByteOrderMark.НеИспользовать).Authorization (Base64 от email:key).Accept: application/json, чтобы сервер не присылал HTML-ответы с ошибками.POST используется для создания объектов, а PUT — для их обновления. Для обновления остатков конкретного товара в CS-Cart чаще всего требуется PUT на эндпоинт товара.Соблюдение этих технических нюансов позволит вам построить надежную интеграцию без использования сторонних скриптов на Python или внешних компонент.