Как правильно передать JSON из 1С в PHP через HTTPЗапрос?

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

При интеграции 1С с веб-сервисами на базе PHP разработчики часто сталкиваются с ситуацией, когда отправленные данные из структуры или соответствия 1С не считываются на стороне сервера. В массиве $_POST ключи оказываются пустыми или вовсе отсутствуют, а обращение к полям вроде $_POST['name'] возвращает пустую строку.

В этой статье мы разберем причины возникновения этой проблемы и рассмотрим два правильных способа передачи и обработки JSON-данных между 1С и PHP.

Почему возникают ошибки при разборе данных на стороне PHP?

Проанализируем базовые ошибки, которые приводят к невозможности распарсить запрос:

  1. Попытка обратиться к внутренним полям JSON напрямую из $_POST: PHP автоматически формирует суперглобальный массив $_POST только на верхнем уровне параметров запроса. Если вы передаете строку вида user={"name":"Ivan"}, то в $_POST['user'] попадет вся сырая JSON-строка. PHP не декодирует вложенные объекты автоматически, поэтому $_POST['name'] будет неопределен.
  2. Отсутствие URL-кодирования (Percent-encoding): Если для запроса указан заголовок application/x-www-form-urlencoded, всё тело запроса должно соответствовать этому формату. Символы, используемые в JSON (двойные кавычки, фигурные скобки, пробелы и переносы строк), ломают структуру POST-запроса, если их предварительно не заэкранировать.
  3. Переносы строк при записи JSON: Настройки по умолчанию при сериализации через ЗаписьJSON могут вставлять автопереносы строк. Неэкранированный символ перевода строки (\r\n) обрывает чтение параметров на веб-сервере.

Способ 1. Передача чистого JSON в теле запроса (Рекомендуемый подход)

Наиболее современным и стандартным способом передачи данных для REST API является отправка чистого JSON в теле HTTP-запроса без лишних POST-оберток. В этом случае PHP считывает входной поток напрямую через php://input.

Рассмотрим реализацию этого способа в 1С:


&НаСервере
Функция ОтправитьJSONНаСервер()
    
    Сервер = "192.168.0.68";
    Ресурс = "/123.php";
    
    HTTP = Новый HTTPСоединение(Сервер);
    
    // Подготовка данных
    Данные = Новый Структура;
    Данные.Вставить("name", "Ivan");
    
    // Формирование JSON без переносов строк
    ПараметрыJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет);
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку(ПараметрыJSON);
    ЗаписатьJSON(ЗаписьJSON, Данные);
    ТекстJSON = ЗаписьJSON.Закрыть();
    
    // Настройка HTTP-запроса
    Запрос = Новый HTTPЗапрос(Ресурс);
    Запрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
    Запрос.УстановитьТелоИзСтроки(ТекстJSON, КодировкаТекста.UTF8);
    
    // Отправка запроса
    ИмяФайлаОтвета = ПолучитьИмяВременногоФайла();
    HTTP.ОтправитьДляОбработки(Запрос, ИмяФайлаОтвета);
    
    // Чтение ответа
    ФайлОтвета = Новый ТекстовыйДокумент;
    ФайлОтвета.Прочитать(ИмяФайлаОтвета, КодировкаТекста.UTF8);
    ОтветСервера = ФайлОтвета.ПолучитьТекст();
    
    Возвращать ОтветСервера;
    
КонецФункции

Применим соответствующий код обработчика на стороне PHP:


<?php
// Получаем сырые данные из тела запроса
$input = file_get_contents('php://input');

if (!empty($input)) {
    // Декодируем JSON в ассоциативный массив
    $data = json_decode($input, true);
    
    if (isset($data['name'])) {
        echo $data['name']; // Выведет: Ivan
    } else {
        echo "Ключ name не найден";
    }
} else {
    echo "empty";
}
?>

Способ 2. Передача JSON в качестве параметра POST-запроса

Если специфика вашего веб-сервера требует использования формата application/x-www-form-urlencoded и передачи данных через переменную (например, user=...), необходимо правильно закодировать JSON-строку средствами 1С и декодировать её на стороне PHP.

Посмотрим на пример формирования запроса в 1С:


&НаСервере
Функция ОтправитьPOSTПараметр()
    
    Сервер = "192.168.0.68";
    Ресурс = "/123.php";
    
    HTTP = Новый HTTPСоединение(Сервер);
    
    Данные = Новый Структура;
    Данные.Вставить("name", "Ivan");
    
    // Отключаем переносы строк
    ПараметрыJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет);
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку(ПараметрыJSON);
    ЗаписатьJSON(ЗаписьJSON, Данные);
    ТекстJSON = ЗаписьJSON.Закрыть();
    
    // Обязательное URL-кодирование строки
    ЗакодированныйJSON = КодироватьСтроку(ТекстJSON, СпособКодированияСтроки.КодировкаURL);
    
    Запрос = Новый HTTPЗапрос(Ресурс);
    Запрос.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
    
    // Передаем параметр и значение
    Запрос.УстановитьТелоИзСтроки("user=" + ЗакодированныйJSON, КодировкаТекста.UTF8);
    
    ИмяФайлаОтвета = ПолучитьИмяВременногоФайла();
    HTTP.ОтправитьДляОбработки(Запрос, ИмяФайлаОтвета);
    
КонецФункции

Разберем принятие такого запроса на стороне PHP:


<?php
if (!empty($_POST['user'])) {
    // Декодируем JSON-строку из POST-параметра
    $userData = json_decode($_POST['user'], true);
    
    echo $userData['name']; // Выведет: Ivan
} else {
    echo "empty";
}
?>

Важные нюансы при работе с типами данных 1С

  1. Ключи коллекций: При использовании объекта Соответствие вместо Структура убедитесь, что все ключи имеют тип Строка. В противном случае метод ЗаписатьJSON() вызовет ошибку выполнения.
  2. Кодировка: Всегда явно указывайте кодировку UTF-8 как при формировании тела запроса в УстановитьТелоИзСтроки(), так и при чтении ответа через ТекстовыйДокумент.Прочитать().
  3. Упрощенный вариант (1С 8.3.23 и новее): В современных версиях платформы для получения JSON-строки из структуры можно использовать функцию глобального контекста ЗаписатьЗначениеJSON(), что существенно сокращает объем кода.
← На главную