При интеграции 1С с веб-сервисами часто возникает задача передать текстовые данные или файл через POST-запрос. Одной из наиболее распространенных проблем является попытка отправить данные как простую строку, в то время как принимающий сервер (например, скрипт на PHP) ожидает данные в формате загрузки файла. В этой статье мы подробно разберем, как правильно сформировать такой запрос, почему стандартные методы могут не работать и как использовать инструменты отладки для достижения результата.
Рассмотрим стандартную ситуацию: вы используете HTTPЗапрос и метод УстановитьТелоИзСтроки(), устанавливая заголовок Content-Type: application/x-www-form-urlencoded. Если на стороне сервера стоит скрипт, обрабатывающий массив $_FILES, такой запрос вернет ошибку (например, "File uploading failed"), так как данные попадут в массив $_POST, а не в структуру файлов.
Для корректной передачи "строки как файла" нам необходимо имитировать работу команды curl -F, которая принудительно использует формат multipart/form-data. Этот формат требует специальной разметки тела запроса с использованием уникальных разделителей (границ).
Прежде чем приступать к написанию кода в 1С, проанализируем, как именно передаются данные через работающие инструменты, такие как curl. Разберем по шагам, как настроить сравнение запросов:
curl, пробросив трафик через прокси Fiddler, чтобы увидеть структуру пакета. Пример команды в консоли:
curl -F "pp=@masageB.txt" -x 127.0.0.1:8888 -k http://your-server.ru/addfile.php
boundary (граница) и специфическую структуру тела, где указаны Content-Disposition, name и filename.Наша задача в 1С — в точности воспроизвести эту структуру.
Посмотрим на пример формирования правильного тела запроса. Важно помнить, что каждый блок данных должен отделяться строкой-разделителем, а в конце заголовков внутри блока обязательно должна быть пустая строка.
Проанализируем ключевой момент: использование правильных символов перевода строки. Для веб-серверов критически важно использовать комбинацию Символы.ВК + Символы.ПС (CRLF).
Рассмотрим пример кода для формирования тела запроса:
&НаСервере
Функция СформироватьТелоЗапроса(ТекстФайла, ИмяФайла, Граница)
Разделитель = "--" + Граница;
ПереносСтроки = Символы.ВК + Символы.ПС;
Тело = Разделитель + ПереносСтроки;
Тело = Тело + "Content-Disposition: form-data; name=""pp""; filename=""" + ИмяФайла + """" + ПереносСтроки;
Тело = Тело + "Content-Type: text/plain" + ПереносСтроки + ПереносСтроки; // Двойной перенос перед текстом
Тело = Тело + ТекстФайла + ПереносСтроки;
Тело = Тело + Разделитель + "--" + ПереносСтроки; // Финальный разделитель с двумя дефисами в конце
Возврат Тело;
КонецФункции
Теперь соберем все воедино в основной функции отправки. Обратите внимание на установку заголовков. Выясним причину, по которой сервер может отклонять запросы от 1С: иногда стандартный заголовок User-Agent (который по умолчанию содержит "1C+Enterprise") блокируется брандмауэрами или настройками веб-сервера.
Рассмотрим реализацию метода отправки:
&НаСервере
Процедура ОтправитьФайлНаСервер()
Сервер = "10.255.1.232";
Ресурс = "/~andy/tsd/addfile.php";
ТекстДляПередачи = "Это содержимое нашего будущего файла";
ИмяФайлаНаСервере = "test_message.txt";
// Генерируем уникальную границу
Граница = "----" + СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");
Заголовки = Новый Соответствие;
// Указываем тип контента и границу
Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Граница);
// Маскируем 1С под обычный браузер (важно!)
Заголовки.Вставить("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
HTTPСоединение = Новый HTTPСоединение(Сервер);
HTTPЗапрос = Новый HTTPЗапрос(Ресурс, Заголовки);
// Формируем тело
СтрокаТела = СформироватьТелоЗапроса(ТекстДляПередачи, ИмяФайлаНаСервере, Граница);
HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаТела, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Попытка
HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Сообщить("Код состояния: " + HTTPОтвет.КодСостояния);
Сообщить("Ответ сервера: " + HTTPОтвет.ПолучитьТелоКакСтроку());
Исключение
Сообщить("Ошибка связи: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Разберем подробнее тонкости, которые могут повлиять на успешный результат:
УстановитьТелоИзСтроки() 1С может добавить метку BOM (Byte Order Mark) в начало данных. Некоторые PHP-скрипты некорректно воспринимают BOM при сохранении файла. Рекомендуется использовать параметр ИспользованиеByteOrderMark.НеИспользовать.Символы.ПС, но протокол HTTP требует именно CRLF (ВК + ПС). Если ваш сервер работает на Linux (Apache/Nginx), он может быть чувствителен к отсутствию Символы.ВК.ЗаписьДанных в буфер, чтобы избежать проблем с кодировками строк.multipart/form-data вручную — единственный надежный способ для мобильной платформы 1С, так как там недоступны внешние компоненты или сложные COM-объекты типа WinHttp.WinHttpRequest.Мы проанализировали ситуацию, когда обычная отправка строки не воспринимается сервером как загрузка файла. Для решения проблемы мы применили формат multipart/form-data, вручную сконструировали тело запроса с соблюдением стандартов boundary и CRLF, а также подменили User-Agent для обхода возможных ограничений сервера. Этот подход является универсальным и работает в любых конфигурациях 1С на платформе 8.3.