Как связать сайт с 1С через HTTP-сервис: примеры кода JS и 1С, решение типичных ошибок

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

Интеграция веб-сайта с базой данных 1С — одна из наиболее частых задач при автоматизации бизнеса. Будь то проверка остатков товаров на складе в режиме реального времени, отправка онлайн-заказов или получение контактных данных клиента — механизмы HTTP-сервисов в 1С предоставляют для этого гибкие и быстрые инструменты. В этой статье мы подробно разберем, как связать фронтенд сайта (код на JavaScript) с бэкендом на стороне 1С, детально проанализируем примеры кода и разберем критические ошибки, с которыми сталкиваются разработчики при первой настройке такого обмена.

Архитектура взаимодействия сайта и 1С

Прежде чем переходить к написанию кода, разберем общую схему взаимодействия. Сайт и 1С общаются между собой по протоколу HTTP с помощью стандартных запросов и ответов. Сценарий выглядит следующим образом:

  1. Пользователь совершает действие на сайте (например, заполняет форму и нажимает кнопку отправки).
  2. JavaScript-код перехватывает это событие, собирает данные формы и инициирует асинхронный HTTP-запрос (обычно GET или POST) к опубликованному HTTP-сервису 1С.
  3. Веб-сервер (IIS или Apache), на котором опубликована база 1С, принимает запрос и перенаправляет его в платформу 1С.
  4. В 1С срабатывает соответствующий метод HTTP-сервиса. Код на встроенном языке обрабатывает входящие параметры, выполняет бизнес-логику (ищет данные, создает документы) и формирует ответ (чаще всего в формате JSON).
  5. Браузер получает этот ответ и с помощью JS обновляет интерфейс страницы без ее полной перезагрузки (технология AJAX).

Рассмотрим по шагам реализацию этой схемы на конкретных примерах.

Шаг 1. Создание веб-формы и отправка GET-запроса на JavaScript

Для начала настроим клиентскую сторону. Предположим, у нас есть простая HTML-форма, в которую пользователь вводит номер лицевого счета, чтобы получить номер телефона, привязанный к нему в базе 1С. Мы напишем скрипт, который будет отправлять данные методом GET с использованием современного API fetch.


<!-- Простая HTML-форма ввода данных -->
<form id="formElem">
    <input type="text" name="pers_acc" placeholder="Введите лицевой счет">
    <input type="submit" value="Получить телефон">
</form>

<script>
    // Навешиваем обработчик на событие отправки формы
    formElem.onsubmit = async (e) => {
        // Предотвращаем стандартную отправку формы с перезагрузкой страницы
        e.preventDefault();
        
        // Получаем данные из полей формы
        let formData = new FormData(formElem);
        let accountNumber = formData.get('pers_acc');
        
        try {
            // Формируем GET-запрос с параметрами в строке URL
            let response = await fetch('http://localhost/BAS/hs/My/Test?name=' + encodeURIComponent(accountNumber));
            
            // Если сервер вернул ошибку, обрабатываем ее
            if (!response.ok) {
                throw new Error('Ошибка сервера: ' + response.status);
            }
            
            // Парсим тело ответа как JSON
            let result = await response.json();
            
            // Выводим результат пользователю
            alert("Телефон: " + result.tel);
            
        } catch (error) {
            console.error('Произошла ошибка при выполнении запроса:', error);
            alert('Не удалось получить данные с сервера.');
        }
    };
</script>

В этом примере метод fetch отправляет запрос асинхронно. Обратите внимание на использование функции encodeURIComponent: она необходима для корректного кодирования спецсимволов и пробелов, которые пользователь может случайно ввести в поле формы.

Шаг 2. Разработка HTTP-сервиса в 1С для обработки GET-запроса

Теперь перейдем в конфигуратор 1С и создадим HTTP-сервис. Назовем его My, а корневой URL укажем как My. Внутри сервиса создадим шаблон URL с именем Test и путем /Test. Для этого шаблона добавим метод GET, который будет вызывать функцию-обработчик TestGET в модуле HTTP-сервиса.

Проанализируем правильный код обработчика в 1С. Нам необходимо считать входящий параметр, найти нужную информацию и вернуть валидный JSON-ответ с корректно заполненными заголовками.


Функция TestGET(Запрос)
    
    // 1. Получаем параметры запроса из URL
    ЛицевойСчет = Запрос.ПараметрыЗапроса.Получить("name");
    
    // Здесь должна быть логика поиска данных в базе 1С.
    // Для примера просто вернем тестовый номер телефона.
    НомерТелефона = "050555555"; 
    
    // 2. Формируем структуру ответа
    СтруктураОтвета = Новый Структура;
    СтруктураОтвета.Вставить("tel", НомерТелефона);
    СтруктураОтвета.Вставить("status", "success");
    
    // 3. Сериализуем структуру в формат JSON
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON, СтруктураОтвета);
    СтрокаJSON = ЗаписьJSON.Закрыть();
    
    // 4. Подготавливаем HTTP-ответ
    Ответ = Новый HTTPСервисОтвет(200); // Код состояния 200 OK
    Ответ.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеBOM.НеИспользовать);
    
    // ВАЖНО: Правильно заполняем заголовки. 
    // Заголовки в HTTPСервисОтвет — это Соответствие, поэтому используем метод Вставить.
    Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
    
    // Разрешаем кросс-доменные запросы (CORS), если сайт и 1С на разных портах/доменах
    Ответ.Заголовки.Вставить("Access-Control-Allow-Origin", "*");
    
    Возврат Ответ;
    
КонецФункции

Разберем частые синтаксические ошибки, которые допускают разработчики в 1С при создании ответов:

Шаг 3. Переход на POST-запросы с передачей JSON-данных

GET-запросы отлично подходят для получения данных, но имеют жесткие ограничения по длине URL-строки и не подходят для изменения состояния данных на сервере. Если вам нужно передать сложный объект, длинный текст или создать новый документ в 1С, необходимо использовать метод POST с передачей структурированного JSON в теле запроса.

Рассмотрим, как модифицировать код на стороне сайта для отправки POST-запроса:


formElem.onsubmit = async (e) => {
    e.preventDefault();
    
    let formData = new FormData(formElem);
    
    // Формируем JS-объект для отправки
    let payload = {
        name: formData.get('name'),
        surname: formData.get('surname')
    };

    try {
        let response = await fetch('http://localhost/BAS/hs/My/Test', {
            method: 'POST',
            headers: {
                // Обязательно указываем тип содержимого, чтобы сервер понял, что это JSON
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(payload) // Преобразуем JS-объект в строку JSON
        });

        if (!response.ok) {
            throw new Error('Ошибка HTTP: ' + response.status);
        }

        let result = await response.json();
        alert('Успешно отправлено! Ответ сервера: ' + result.status);
        
    } catch (error) {
        console.error('Ошибка POST запроса:', error);
    }
};

Теперь напишем обработчик метода POST на стороне 1С. Нам необходимо прочитать тело запроса, десериализовать его обратно в Структуру 1С и выполнить обработку:


Функция TestPOST(Запрос)
    
    Ответ = Новый HTTPСервисОтвет(201); // Код 201 Created для успешного POST
    Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
    Ответ.Заголовки.Вставить("Access-Control-Allow-Origin", "*");
    
    // 1. Извлекаем тело запроса в виде строки
    СтрокаТела = Запрос.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
    
    Если ПустаяСтрока(СтрокаТела) Тогда
        Ответ.КодСостояния = 400; // Bad Request
        Возврат Ответ;
    КонецЕсли;
    
    // 2. Десериализуем JSON в структуру 1С
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(СтрокаТела);
    ДанныеЗапроса = ПрочитатьJSON(ЧтениеJSON);
    ЧтениеJSON.Закрыть();
    
    // Извлекаем значения параметров, отправленных с сайта
    ИмяПользователя = ДанныеЗапроса.name;
    ФамилияПользователя = ДанныеЗапроса.surname;
    
    // Выполняем запись данных или поиск (например, создание контрагента)
    // ... логика работы с базой 1С ...
    
    // 3. Формируем ответ клиенту
    РезультатСтруктура = Новый Структура;
    РезультатСтруктура.Вставить("status", "success");
    РезультатСтруктура.Вставить("message", "Данные пользователя " + ИмяПользователя + " сохранены.");
    
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON, РезультатСтруктура);
    СтрокаОтвета = ЗаписьJSON.Закрыть();
    
    Ответ.УстановитьТелоИзСтроки(СтрокаОтвета, КодировкаТекста.UTF8, ИспользованиеBOM.НеИспользовать);
    Возврат Ответ;
    
КонецФункции

Шаг 4. Решение проблемы CORS (Cross-Origin Resource Sharing)

В процессе отладки запросов из браузера разработчики неизбежно сталкиваются с ситуацией, когда запрос блокируется политикой безопасности браузера. В консоли разработчика (F12) появляется ошибка вида: Access to fetch at ... from origin ... has been blocked by CORS policy.

Это происходит потому, что браузер запрещает веб-страницам делать запросы к другому домену или порту (например, ваш сайт расположен на mysite.ru, а 1С — на localhost или поддомене 1c.mysite.ru), если сервер 1С явно не разрешил такое взаимодействие.

Для решения этой проблемы необходимо сделать следующее:

  1. В заголовках всех ответов 1С обязательно должен присутствовать заголовок: Ответ.Заголовки.Вставить("Access-Control-Allow-Origin", "*"); (или вместо * укажите конкретный адрес вашего сайта для повышения безопасности).
  2. При отправке сложных запросов (например, POST-запросов с заголовком Content-Type: application/json) браузер сначала отправляет предварительный пустой запрос методом OPTIONS (так называемый preflight-запрос), чтобы проверить права. Если 1С не умеет отвечать на этот метод, основной POST-запрос даже не выполнится.

Добавим обработчик метода OPTIONS в наш HTTP-сервис 1С:


Функция TestOPTIONS(Запрос)
    
    // Метод OPTIONS должен возвращать пустой ответ с кодом 204 No Content или 200 OK
    Ответ = Новый HTTPСервисОтвет(204); 
    
    // Указываем, откуда разрешены запросы
    Ответ.Заголовки.Вставить("Access-Control-Allow-Origin", "*");
    // Разрешаем методы
    Ответ.Заголовки.Вставить("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
    // Разрешаем заголовки, которые браузер передает в запросе
    Ответ.Заголовки.Вставить("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
    
    Возврат Ответ;
    
КонецФункции

Шаг 5. Обеспечение безопасности и авторизации

Оставлять HTTP-сервис 1С открытым для всех пользователей интернета без авторизации крайне небезопасно. Существует два основных подхода к защите интеграции:

Подход А. Использование бэкенда сайта в качестве прокси-сервера (Рекомендуемый)

Вместо того чтобы отправлять запросы из браузера пользователя напрямую в 1С, отправляйте их на ваш сервер бэкенда (написанный на PHP, Python, NodeJS). Сервер сайта, в свою очередь, делает запрос в 1С. Преимущества очевидны:

Подход Б. Публикация с ограниченным гостевым пользователем в 1С

Если проксирование реализовать невозможно, настройте анонимный доступ к базе 1С через файл публикации default.vrd. В нем прописываются логин и пароль специально созданного пользователя 1С:

<point base="/BAS" ib="File="C:\Base";Usr=WebGuest;Pwd=SecretPassword;" ...>

При этом пользователю WebGuest в конфигураторе 1С необходимо дать минимальные права. У него должна быть роль, позволяющая только запускать HTTP-сервисы, и права на чтение/запись только тех объектов, которые непосредственно участвуют в обмене. Полный доступ к метаданным или интерфейсу системы у этой учетной записи должен быть категорически закрыт.

Мы подробно разобрали весь процесс интеграции: от написания скриптов отправки данных на стороне сайта до обработки запросов внутри 1С с решением проблем кодировок, CORS-политики и безопасности. Следуя этим рекомендациям, вы сможете построить надежный и быстрый мост обмена данными между вашим веб-ресурсом и информационной базой 1С.

← На главную