Почему HTTPСоединение в 1С возвращает ошибку 404 и как правильно настроить обращение к локальному веб-серверу?

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

При интеграции 1С с внешними веб-сервисами и локальными сайтами разработчики нередко сталкиваются с ситуацией, когда скрипт без проблем открывается в браузере по адресу 127.0.0.1 или localhost, однако при попытке выполнить запрос через объект HTTPСоединение платформа возвращает ошибку «Ошибка работы с Интернет: ресурс не найден (404)». При этом в тексте ошибки может неожиданно фигурировать посторонний веб-сервер (например, IIS вместо развернутого Apache).

Разберем детально, почему возникает подобная ситуация, как архитектура клиент-серверной базы 1С влияет на сетевые вызовы и как правильно формировать запросы.

Причина 1. Путаница контекста выполнения: Клиент или Сервер

Проанализируем архитектуру вызова. Если база данных работает в клиент-серверном режиме, критически важно обращать внимание на директивы компиляции процедур и функций (&НаСервере, &НаСервереБезКонтекста, &НаКлиенте):

  1. Выполнение на сервере: если конструктор HTTPСоединение и отправка запроса вызываются в серверном контексте, сетевой запрос отправляется операционной системой самого сервера «1С:Предприятия». В этом случае адрес 127.0.0.1 (loopback) означает локальную петлю именно физического или виртуального сервера 1С, а не рабочего компьютера разработчика. Если на сервере 1С на порту 80 работает системный веб-сервер (например, IIS), запрос попадет именно туда, вернув ошибку 404 от IIS, так как искомый PHP-скрипт лежит на ПК разработчика.
  2. Выполнение на клиенте: если процедура выполняется с директивой &НаКлиенте (в тонком или толстом клиенте), запрос пойдет непосредственно с машины пользователя. Однако помните, что в веб-клиенте объект HTTPСоединение на стороне клиента не поддерживается.

Выясним, как решить проблему сетевой адресации в серверном коде:

  1. Вместо локального адреса 127.0.0.1 или имени localhost укажем реальный IP-адрес рабочего компьютера в локальной сети (например, 192.168.1.50) либо его сетевое DNS-имя.
  2. Убедимся, что на компьютере с веб-сервером брандмауэр разрешает входящие подключения на используемый веб-сервером порт от IP-адреса сервера 1С.

Причина 2. Ошибки в синтаксисе относительного пути

Рассмотрим синтаксис метода Получить объекта HTTPСоединение. В конструктор соединения передаются адрес хоста и порт:


ПараметрыСоединенияСервер = "192.168.1.50";
ПараметрыСоединенияПорт   = 80;
HTTP = Новый HTTPСоединение(ПараметрыСоединенияСервер, ПараметрыСоединенияПорт);

При вызове метода получения данных первым параметром должен передаваться исключительно относительный путь к ресурсу на сервере, а не повторный ввод IP-адреса или имени узла:

  1. Неправильно: HTTP.Получить("127.0.0.1/index.php", ФайлРезультата); — в этом случае веб-сервер ищет ресурс по пути /127.0.0.1/index.php относительно корня сайта и возвращает ошибку 404.
  2. Правильно: HTTP.Получить("/index.php", ФайлРезультата); или HTTP.Получить("index.php", ФайлРезультата);.

Причина 3. Конфликты портов и системных служб Windows

Если Apache и 1С запущены на одной машине, но в ошибке все равно возвращается ответ от IIS, посмотрим на распределение портов в операционной системе Windows. Служба World Wide Web Publishing Service (W3SVC) или драйвер http.sys могут перехватывать порт 80 на определенных сетевых интерфейсах еще до того, как Apache успеет обработать запрос. Чтобы исключить подобные конфликты:

  1. Переведем Apache на другой свободный порт (например, 8080 или 8088) в конфигурационном файле httpd.conf.
  2. Явно укажем этот порт во втором параметре конструктора HTTPСоединение.

Рекомендуемый современный подход: использование объекта HTTPЗапрос

Вызов метода HTTPСоединение.Получить() с передачей строки пути и имени выходного файла является устаревшей практикой. В актуальных версиях платформы рекомендуется использовать связку HTTPЗапрос и HTTPОтвет. Это избавляет от необходимости обязательно писать ответ во временный файл и позволяет безопасно анализировать код ответа сервера.

Разберем по шагам правильную реализацию HTTP-запроса:


// 1. Формируем сетевые параметры
СерверХост = "192.168.1.50"; // Реальный IP или имя машины, а не 127.0.0.1 для серверного кода
ПортСервера = 8080;
Таймаут = 30;

// 2. Инициализируем соединение с отключением системного прокси (если нужно обращаться напрямую)
Прокси = Новый ИнтернетПрокси(Ложь);
HTTPСоединение = Новый HTTPСоединение(СерверХост, ПортСервера, , , Прокси, Таймаут);

// 3. Формируем относительный путь запроса
ОтносительныйURL = "/index.php";
Запрос = Новый HTTPЗапрос(ОтносительныйURL);

// При необходимости передаем нужный Host для виртуальных хостов
Запрос.Заголовки.Вставить("Host", СерверХост);

// 4. Отправляем запрос и анализируем результат
Попытка
    Ответ = HTTPСоединение.Получить(Запрос);
    
    Если Ответ.КодСостояния = 200 Тогда
        СтрокаОтвета = Ответ.ПолучитьТелоКакСтроку();
        // Обрабатываем полученный ответ (например, парсим JSON)
    Иначе
        // Обрабатываем нештатный статус сервера (404, 500 и т.д.) без падения в исключение
        ВызватьИсключение СтрШаблон("Сервер вернул ошибку: %1 (%2)", Ответ.КодСостояния, Ответ.ПолучитьТелоКакСтроку());
    КонецЕсли;
Исключение
    ИнформацияОбОшибке = ОписаниеОшибки();
    // Логируем ошибку сети или подключения
    ВызватьИсключение ИнформацияОбОшибке;
КонецПопытки;

Такой подход делает код надежным, изолирует логику от неожиданных перехватов системным прокси-сервером и четко разграничивает хост и относительный путь к ресурсу.

← На главную