При разработке механизмов интеграции 1С с веб-сайтами часто возникает задача автоматического скачивания изображений. Однако нередко разработчики сталкиваются с ситуацией, когда код вроде бы отрабатывает без ошибок, но результирующий файл имеет подозрительно малый вес (например, 160–170 байт) и не открывается как изображение. В этой статье мы подробно разберем, почему это происходит, как проанализировать содержимое "сломанного" файла и какие существуют способы решения этой проблемы в зависимости от версии вашей платформы.
Первым делом проанализируем ситуацию. Если вы скачиваете картинку, которая на сайте весит 42 Кб, а локально сохраняется файл размером 162 байта, это явный признак того, что сервер передал вам не двоичные данные изображения, а текстовое сообщение об ошибке или перенаправлении. 1С послушно записывает полученный ответ в файл, расширение которого вы указали как .jpg, но формат внутри остается текстовым.
Для диагностики откройте полученный файл обычным блокнотом (Notepad). Скорее всего, вместо набора непонятных символов (бинарных данных) вы увидите нечто подобное:
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
Этот текст сообщает нам об ошибке протокола HTTP: 301 Moved Permanently. Это означает, что ресурс был окончательно перемещен на другой адрес, и сервер ожидает, что клиент (в данном случае 1С) выполнит повторный запрос по новому адресу, указанному в заголовке ответа Location.
Разберем, почему на одном компьютере код может работать, а на другом — нет. Ключевым моментом здесь является версия платформы 1С:Предприятие и установленный в конфигурации режим совместимости.
В современных версиях платформы (начиная с 8.3.8) объект HTTPСоединение научился обрабатывать перенаправления (редиректы) автоматически. Однако, если ваша конфигурация работает в режиме совместимости с версиями 8.2 или ранними 8.3 (например, 8.3.10 в режиме совместимости 8.2.13), платформа ведет себя по-старому: она получает ответ 301, не переходит по ссылке и просто возвращает тело этого ответа разработчику.
Рассмотрим пример кода, который часто используется для получения картинки:
Соединение = Новый HTTPСоединение(ИмяСервера, , , , , , Новый ЗащищенноеСоединениеOpenSSL());
Запрос = Новый HTTPЗапрос(СсылкаФото);
Ответ = Соединение.Получить(Запрос);
ДвоичныеДанныеКартинки = Ответ.ПолучитьТелоКакДвоичныеДанные();
Картинка = Новый Картинка(ДвоичныеДанныеКартинки);
Картинка.Записать("C:\Temp\image.jpg");
Если режим совместимости ниже 8.3.8, этот код сохранит HTML-текст вместо картинки. Если режим выше 8.3.8, платформа сама увидит заголовок Location и скачает файл по новому адресу.
Вторая частая проблема — ошибка «Проверка удаленного узла не произошла». Это напрямую связано с использованием ЗащищенноеСоединениеOpenSSL(). При работе через защищенный протокол HTTPS 1С пытается проверить валидность сертификата сайта. Проблема может возникнуть, если:
HTTPСоединение сильно ограничена или работает некорректно.Проанализируем более простой метод получения данных — использование встроенной функции КопироватьФайл. Удивительно, но эта функция во многих случаях работает лучше, чем объект HTTPСоединение, так как она использует системные механизмы операционной системы для работы с сетью.
СсылкаФото = "https://freshfood.com.ua/content/images/2/53745923386131.jpg";
ПутьЛокальный = "C:\Bases_1C\bck\image.jpg";
КопироватьФайл(СсылкаФото, ПутьЛокальный);
Если этот код выдает ошибку доступа или проверки узла, значит, проблема в системных настройках безопасности или отсутствии доступа к URL с сервера. Если же на локальном компьютере программиста код работает, а на сервере — нет, проверьте права доступа пользователя, под которым запущен агент сервера 1С, и настройки брандмауэра.
Если вы не можете изменить режим совместимости конфигурации, вам придется научить 1С обрабатывать редиректы вручную. Для этого необходимо проверить код состояния ответа. Рассмотрим алгоритм:
Ответ.КодСостояния.Пример реализации:
Соединение = Новый HTTPСоединение(ИмяСервера, , , , , , Новый ЗащищенноеСоединениеOpenSSL());
Запрос = Новый HTTPЗапрос(СсылкаФото);
Ответ = Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 301 Или Ответ.КодСостояния = 302 Тогда
НовыйАдрес = Ответ.Заголовки.Получить("Location");
// Здесь нужно проанализировать НовыйАдрес: он может быть абсолютным или относительным
// И выполнить повторный запрос
КонецЕсли;
Будьте внимательны: иногда серверы возвращают "кривые" заголовки Location, которые содержат дублирующиеся части пути. В таком случае потребуется строковая обработка URL перед повторным запросом.
Если штатные средства 1С в вашей версии платформы категорически отказываются работать с современными сайтами по HTTPS или некорректно обрабатывают редиректы, лучшим выходом будет использование объекта WinHttp.WinHttpRequest.5.1. Этот объект обращается напрямую к библиотекам Windows, которые обновляются вместе с операционной системой и поддерживают все современные стандарты.
Разберем пример реализации этого метода:
Функция СкачатьКартинкуЧерезWinHttp(URL, ПутьКФайлу)
Попытка
HttpЗапрос = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
HttpЗапрос.Option(2, 1251); // Кодировка
HttpЗапрос.Open("GET", URL, Ложь);
HttpЗапрос.Send();
Если HttpЗапрос.Status = 200 Тогда
Поток = Новый COMОбъект("ADODB.Stream");
Поток.Type = 1; // Binary
Поток.Open();
Поток.Write(HttpЗапрос.ResponseBody);
Поток.SaveToFile(ПутьКФайлу, 2); // 2 - перезаписать
Поток.Close();
Возврат Истина;
КонецЕсли;
Исключение
Сообщить("Ошибка при скачивании: " + ОписаниеОшибки());
КонецПопытки;
Возврат Ложь;
КонецФункции
Этот метод считается наиболее надежным для работы на старых платформах (8.2 и ранние 8.3), так как он "прощает" отсутствие настроек OpenSSL в 1С и отлично справляется с большинством защищенных соединений.
Имитация браузера (User-Agent): Некоторые современные серверы (особенно под управлением nginx) блокируют запросы, если в них не указан заголовок User-Agent. Они считают такие запросы атакой ботов. Чтобы этого избежать, всегда добавляйте заголовок в ваш HTTPЗапрос:
Запрос.Заголовки.Вставить("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
Кэширование: Если вы столкнулись с тем, что картинка на сайте обновилась, а 1С скачивает старую версию, попробуйте добавить к адресу случайный параметр, например: "mysite.com/image.jpg?v=" + Формат(ТекущаяДата(), "ДФ=yyyyMMddHHmmss"). Это заставит сервер отдать свежий файл, минуя кэш.
Подводя итог: если вы видите файл размером в 160 байт, не ищите проблему в методе записи картинки на диск. Проблема кроется в ответе сервера. Проверьте содержимое файла, убедитесь в актуальности режима совместимости вашей конфигурации и при необходимости используйте COM-объекты для обхода ограничений старых версий 1С.