При интеграции 1С со сторонними веб-сервисами, сайтами или внутренними скриптами разработчики часто сталкиваются с ситуацией: в адресной строке веб-браузера запрос успешно выполняется и возвращает корректный результат, а при вызове того же адреса из программного кода 1С через объект HTTPСоединение возвращается код состояния 404 Not Found. Разберем причины такого поведения платформы и посмотрим, как правильно настроить выполнение HTTP-запросов.
Рассмотрим исходный пример кода, вызывавший ошибку:
ИмяСервераHTTP = "188.188.188.188";
ПортHTTP = 8088;
Соединение = Новый HTTPСоединение(ИмяСервераHTTP, ПортHTTP,,,,60,);
Попытка
ИмяВыходногоФайла = ПолучитьИмяВременногоФайла("txt");
Запрос = Новый HTTPЗапрос;
Запрос.АдресРесурса = "/resurs/test.php";
Ответ = Соединение.Получить(Запрос, ИмяВыходногоФайла);
Если Ответ.КодСостояния <> 200 Тогда
Сообщить("Ошибка: " + Ответ.КодСостояния);
Иначе
Сообщить("Удача");
КонецЕсли;
Исключение
Сообщить("Ошибка запроса! " + ОписаниеОшибки());
КонецПопытки;
Проанализируем ситуацию: когда разработчик тестировал обращение в веб-браузере, он вводил адрес вида 188.188.188.188/resurs/test.php. Браузер по умолчанию отправляет запросы по стандартному порту 80 (для протокола HTTP) или 443 (для протокола HTTPS). Однако в коде 1С в параметрах конструктора HTTPСоединение был явно указан порт 8088. На этом порту либо не был настроен веб-сервер, либо на нем был развернут другой виртуальный хост, не содержащий нужного каталога и файла, из-за чего веб-сервер возвращал ответ 404.
Если веб-сервер принимает входящие соединения на стандартном порту, явное указание порта в конструкторе следует опустить или передать значение Неопределено. В таком случае платформа 1С автоматически подставит порт 80 (или 443, если в параметрах защиты передан объект ЗащищенноеСоединениеOpenSSL).
Посмотрим на исправленный вариант инициализации соединения:
ИмяСервераHTTP = "188.188.188.188";
// Не указываем порт явно, если используется стандартный веб-порт 80
Соединение = Новый HTTPСоединение(ИмяСервераHTTP,,,,,60);
Обратите внимание на синтаксис первого параметра: в параметр Сервер объекта HTTPСоединение передается только чистое доменное имя или IP-адрес без указания протокола (http:// или https://) и без завершающих слэшей.
Если порт указан верно, но веб-сервер все равно возвращает код 404 или ошибку доступа, выясним другие возможные причины различий:
HTTPСоединение доменное имя либо явно добавляйте заголовок Host:
Запрос = Новый HTTPЗапрос("/resurs/test.php");
Запрос.Заголовки.Вставить("Host", "mysite.domain");
&НаСервере или регламентном задании), запрос отправляется от имени самого сервера 1С, а не с пользовательского ПК. На сервере могут быть заблокированы порты брандмауэром или отсутствовать маршрут до IP-адреса.3xx считывать целевой адрес из заголовка Location ответа.ИнтернетПрокси и передавать его в конструктор соединения.В типовых задачах интеграции сохранять ответ веб-сервера во временный файл на диске через ПолучитьИмяВременногоФайла необязательно. Вызов метода Получить() без указания имени файла сохраняет ответ в оперативной памяти, что существенно ускоряет обработку запросов и исключает лишние операции с файловой системой.
Разберем эталонный пример отправки GET-запроса и чтения ответа в строку:
ИмяСервера = "188.188.188.188";
ПутьКРесурсу = "/resurs/test.php";
// Создаем соединение с таймаутом 60 секунд
Соединение = Новый HTTPСоединение(ИмяСервера, , , , , 60);
Запрос = Новый HTTPЗапрос(ПутьКРесурсу);
Запрос.Заголовки.Вставить("Accept", "text/html,application/xhtml+xml,application/json");
Попытка
Ответ = Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 200 Тогда
// Считываем тело ответа напрямую в строку с указанием кодировки UTF-8
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
Сообщить("Успешный ответ: " + ТекстОтвета);
Иначе
Сообщить("Ошибка HTTP: " + Строка(Ответ.КодСостояния));
// Читаем тело ответа с подробностями об ошибке от веб-сервера
Сообщить("Текст ошибки: " + Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8));
КонецЕсли;
Исключение
Сообщить("Сетевая ошибка при выполнении запроса: " + ОписаниеОшибки());
КонецПопытки;
Для защищенных соединений HTTPS в седьмой параметр конструктора HTTPСоединение передается объект Новый ЗащищенноеСоединениеOpenSSL(), а стандартный порт 443 также подставляется платформой автоматически.