Как правильно отправить JSON-запрос из 1С, чтобы сервер корректно принял данные?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С с внешними веб-сервисами программисты часто сталкиваются с ситуацией, когда код кажется верным, данные сериализуются в JSON без ошибок, но принимающая сторона (сервер) либо возвращает ошибку 404 Not Found, либо заявляет, что данные пришли в «битом» или неверном формате. Рассмотрим типичную ситуацию: вы отправляете структуру с параметрами обновления заказа, а сервер в логах отображает странную конструкцию, где весь ваш JSON-текст помещен в ключ с пустым значением. Разберем по шагам, почему так происходит и как это исправить.

Выясним причину: почему сервер «не видит» JSON?

Проанализируем ситуацию, описанную в теме. Когда мы используем объект HTTPЗапрос и устанавливаем тело из строки, 1С просто передает набор байтов. Если мы не сообщаем серверу, что именно находится внутри этого набора байтов, сервер пытается угадать формат самостоятельно. Чаще всего веб-серверы по умолчанию ожидают формат application/x-www-form-urlencoded (стандартная отправка данных из HTML-формы). В этом формате данные передаются в виде пар ключ=значение.

Посмотрим на пример из логов сервера: {"data":{"{...}":null}}. Это происходит потому, что сервер, не найдя символа равенства =, воспринял всю вашу JSON-строку как один огромный ключ, а значение для этого ключа оставил пустым (null). Чтобы этого избежать, необходимо явно указать тип контента в заголовках запроса.

Решение 1: Установка правильного заголовка Content-Type

Основное решение проблемы заключается в добавлении заголовка Content-Type. Это сообщает серверу: «В теле запроса находится именно JSON, распарси его соответствующим образом». Изменим код отправки следующим образом:


// Подготовка данных
JSON = Новый ЗаписьJSON;
JSON.УстановитьСтроку();
ПараметрыЗапроса = Новый Структура("id_order,status", 1, 2);
ЗаписатьJSON(JSON, ПараметрыЗапроса);
ТелоЗапроса = JSON.Закрыть();

// Формирование запроса
HTTPЗапрос = Новый HTTPЗапрос("/api/orders/update");
// Указываем серверу формат данных
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json"); 
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса);

// Отправка
Ответ = Соединение.ОтправитьДляОбработки(HTTPЗапрос);

Как только мы добавляем Content-Type: application/json, сервер переключает свой обработчик в режим чтения JSON, и данные начинают «попадать» в нужные поля базы данных.

Решение 2: Проблема невидимых символов (BOM)

Иногда даже после добавления заголовков сервер продолжает выдавать ошибку 400 Bad Request или 500 Internal Server Error. Выясним причину в деталях: 1С при использовании метода УстановитьТелоИзСтроки может автоматически добавлять в начало строки метку порядка байтов (BOM — Byte Order Mark). Это специальные невидимые символы, которые указывают на кодировку UTF-8.

Многие современные веб-фреймворки (написанные на PHP, Python или Go) не ожидают увидеть BOM в начале JSON-пакета и воспринимают его как синтаксическую ошибку («Unexpected character»). Рассмотрим, как передать данные максимально «чисто»:


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

Этот подход гарантирует, что сервер получит «чистый» JSON-текст без технических префиксов, которые могут сломать парсер.

Решение 3: Ожидание ответа в формате JSON (заголовок Accept)

Обратим внимание на сообщение №2 из обсуждения, где автор получил в ответ огромный кусок HTML-кода с ошибкой 404. Чтобы сервер возвращал ошибки не в виде красивых веб-страниц для людей, а в виде структурированного JSON для программы, рекомендуется добавить заголовок Accept. Проанализируем, как это изменит взаимодействие:

HTTPЗапрос.Заголовки.Вставить("Accept", "application/json");

Теперь, если заказ не будет найден, сервер вместо HTML-страницы «Not Found» вернет JSON-объект вида {"error": "Order not found"}, который 1С сможет легко прочитать и вывести пользователю в понятном виде.

Решение 4: Проверка HTTP-метода (PUT против POST)

В исходном примере автор использует Соединение.ОтправитьДляОбработки(HTTPЗапрос), что соответствует методу POST. Однако в архитектуре REST для операций обновления данных (UPDATE) часто зарезервированы методы PUT или PATCH. Если сервер строго следует стандартам, он может отклонить POST-запрос на адрес обновления данных.

Разберем, как вызвать произвольный метод в 1С:


// Вместо ОтправитьДляОбработки используем ВызватьHTTPМетод
Ответ = Соединение.ВызватьHTTPМетод("PUT", HTTPЗапрос);

Проверьте документацию к API, с которым вы интегрируетесь. Если там указано PUT, то использование ВызватьHTTPМетод является обязательным.

Инструменты для отладки: как увидеть запрос «глазами сервера»?

Если решение все еще не найдено, проанализируем ситуацию с помощью внешних сервисов. Одним из самых эффективных способов является использование сервиса Webhook.site. Порядок действий прост:

  1. Зайдите на сайт (он сгенерирует уникальную ссылку).
  2. В коде 1С временно замените адрес вашего сервера на эту ссылку.
  3. Отправьте запрос из 1С.
  4. На сайте в режиме реального времени вы увидите: все пришедшие заголовки, тело запроса в сыром виде (RAW) и наличие лишних символов (BOM).

Это позволит мгновенно понять, на чьей стороне проблема: 1С неправильно формирует пакет или сервер неправильно его интерпретирует.

Подведем итог: для успешной передачи JSON из 1С всегда проверяйте наличие заголовка Content-Type, отключайте ByteOrderMark и используйте подходящий HTTP-метод. Эти три шага решают до 95% проблем при интеграции программных продуктов 1С с внешними системами.

← На главную