При интеграции 1С с внешними веб-сервисами программисты часто сталкиваются с ситуацией, когда код кажется верным, данные сериализуются в JSON без ошибок, но принимающая сторона (сервер) либо возвращает ошибку 404 Not Found, либо заявляет, что данные пришли в «битом» или неверном формате. Рассмотрим типичную ситуацию: вы отправляете структуру с параметрами обновления заказа, а сервер в логах отображает странную конструкцию, где весь ваш JSON-текст помещен в ключ с пустым значением. Разберем по шагам, почему так происходит и как это исправить.
Проанализируем ситуацию, описанную в теме. Когда мы используем объект HTTPЗапрос и устанавливаем тело из строки, 1С просто передает набор байтов. Если мы не сообщаем серверу, что именно находится внутри этого набора байтов, сервер пытается угадать формат самостоятельно. Чаще всего веб-серверы по умолчанию ожидают формат application/x-www-form-urlencoded (стандартная отправка данных из HTML-формы). В этом формате данные передаются в виде пар ключ=значение.
Посмотрим на пример из логов сервера: {"data":{"{...}":null}}. Это происходит потому, что сервер, не найдя символа равенства =, воспринял всю вашу JSON-строку как один огромный ключ, а значение для этого ключа оставил пустым (null). Чтобы этого избежать, необходимо явно указать тип контента в заголовках запроса.
Основное решение проблемы заключается в добавлении заголовка 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, и данные начинают «попадать» в нужные поля базы данных.
Иногда даже после добавления заголовков сервер продолжает выдавать ошибку 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-текст без технических префиксов, которые могут сломать парсер.
Обратим внимание на сообщение №2 из обсуждения, где автор получил в ответ огромный кусок HTML-кода с ошибкой 404. Чтобы сервер возвращал ошибки не в виде красивых веб-страниц для людей, а в виде структурированного JSON для программы, рекомендуется добавить заголовок Accept. Проанализируем, как это изменит взаимодействие:
HTTPЗапрос.Заголовки.Вставить("Accept", "application/json");
Теперь, если заказ не будет найден, сервер вместо HTML-страницы «Not Found» вернет JSON-объект вида {"error": "Order not found"}, который 1С сможет легко прочитать и вывести пользователю в понятном виде.
В исходном примере автор использует Соединение.ОтправитьДляОбработки(HTTPЗапрос), что соответствует методу POST. Однако в архитектуре REST для операций обновления данных (UPDATE) часто зарезервированы методы PUT или PATCH. Если сервер строго следует стандартам, он может отклонить POST-запрос на адрес обновления данных.
Разберем, как вызвать произвольный метод в 1С:
// Вместо ОтправитьДляОбработки используем ВызватьHTTPМетод
Ответ = Соединение.ВызватьHTTPМетод("PUT", HTTPЗапрос);
Проверьте документацию к API, с которым вы интегрируетесь. Если там указано PUT, то использование ВызватьHTTPМетод является обязательным.
Если решение все еще не найдено, проанализируем ситуацию с помощью внешних сервисов. Одним из самых эффективных способов является использование сервиса Webhook.site. Порядок действий прост:
Это позволит мгновенно понять, на чьей стороне проблема: 1С неправильно формирует пакет или сервер неправильно его интерпретирует.
Подведем итог: для успешной передачи JSON из 1С всегда проверяйте наличие заголовка Content-Type, отключайте ByteOrderMark и используйте подходящий HTTP-метод. Эти три шага решают до 95% проблем при интеграции программных продуктов 1С с внешними системами.