Некоторое время назад в ходе реализации одного проекта потребовалось организовать автоматическую передачу данных на веб-сервер посредством регламентного задания.
Покопавшись прежде всего в мануалах, синтаксис-помощнике 1С Предприятия, порыскав в Сети, я с удивлением обнаружил наличие отсутствия каких-либо вменяемых материалов по теме. Вернее, материалы в Сети есть, но там больше вопросы с абстрактными ответами.
Ну что ж, пришлось напрячь мозг и докапываться до сути, в первый раз, что ли.
Все нижеприведённые примеры кода всего лишь примеры, хоть и взяты из рабочей конфигурации.
Для передачи данных на сервер методом POST в 1С Предприятии 8.1 применяется метод HTTPСоединение
ОтправитьДляОбработки(<Источник>, <Адрес ресурса>, <Имя выходного файла>, <Заголовки>)
(подробнее см. СП)
Прежде всего необходимо создать файл отправки данных (собственно содержимое POST-запроса) и, при необходимости, подготовить двоичные данные.
Определяем разделитель разделов — границу boundary в POST-запросе.
В качестве границы может быть использована строка, состоящая из латинских букв и цифр.
Чтобы ничего не выдумывать, воспользуемся штатным классом УникальныйИдентификатор.
//Подготовка переменных
Boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");
//Определяем имя файла ответа от веб-сервера
ИмяФайлаОтвета = КаталогВременныхФайлов() + "answer.tmp";
Подготавливаем двоичные данные. В моём случае это файл архива zip, но может быть что угодно, хоть изображение.
//Какой-то ранее созданный архив
ИмяФайлаДанных = "data.zip";
Вот здесь ВНИМАНИЕ!
Только нижеследующим способом в 1С Предприятии можно передать двоичные данные на сервер, в связи с отсутвием в системе средств чтения файлов в обычную строку. Впрочем, двоичные данные лучше закодировать, иначе при приёме на веб-сервере файл может быть повреждён или не принят вовсе, если он будет содержать URL-значащие символы.
Декодирование содержимого файла на сервере можно осуществить при помощи функции php base64_decode() или аналогичных для используемого вами серверного ПО.
//Закодируем содержимое файла по Base64, то есть преобразуем его к URL-неактивному виду.
СодержимоеZIP = Base64Строка(Новый ДвоичныеДанные(ИмяФайлаДанных));
Следует также помнить об ограничениях хостинга и контролировать размер передаваемых данных. Как правило, для php это 2Мб. (см. файл /usr/local/php5/php.ini)
; Maximum allowed size for uploaded files.
upload_max_filesize = 2M
В противном случе, на веб-сервере вы получите пустой POST-запрос.
//Проверим размер кодированного файла.
Если СтрДлина(СодержимоеZIP) > ДопустимыйРазмерФайлаВБайтах Тогда
//Какие-то ваши действия, возможно
Возврат;
КонецЕсли;
Создаём файл отправки или содержимое POST-запроса.
ИмяФайлаОтправки = КаталогВременныхФайлов() + "post.txt";
ФайлОтправки = Новый ЗаписьТекста(ИмяФайлаОтправки, КодировкаТекста.ANSI, Символы.ПС, ЛОЖЬ);
//Определяем раздел двоичных данных
ФайлОтправки.ЗаписатьСтроку("--" + Boundary);
ФайлОтправки.ЗаписатьСтроку("Content-Disposition: form-data; name=""data""; filename=""" + ИмяФайлаДанных + """");
//С таким же успехом в Content-Type можно указать application/x-octet-stream
ФайлОтправки.ЗаписатьСтроку("Content-Type: application/x-zip-compressed" + Символы.ПС + Символы.ПС);
ФайлОтправки.ЗаписатьСтроку(СодержимоеZIP);
ФайлОтправки.ЗаписатьСтроку("--" + Boundary);
//Определяем раздел для каких либо других POST-данных, например содержимого полей виртуальной HTML-формы.
ФайлОтправки.ЗаписатьСтроку("--" + Boundary);
//Соответствует HTML-тэгу input type="submit" name="submit" value="Submit" /
ФайлОтправки.ЗаписатьСтроку("Content-disposition: form-data; name=""submit""" + Символы.ПС);
ФайлОтправки.ЗаписатьСтроку("1");
ФайлОтправки.ЗаписатьСтроку("--" + Boundary);
ФайлОтправки.ЗаписатьСтроку("--" + Boundary);
//Соответствует HTML-тэгу
//input type="text" name="some_field" value="Some text" /
ФайлОтправки.ЗаписатьСтроку("Content-disposition: form-data; name=""some_field""" + Символы.ПС);
ФайлОтправки.ЗаписатьСтроку("Some text");
ФайлОтправки.ЗаписатьСтроку("--" + Boundary);
ФайлОтправки.Закрыть();
Формируем заголовок POST-запроса.
ЗаголовокHTTP = Новый Соответствие();
//При необходимости зададим Referer, например таким образом
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
СерверИсточник = НСтр(СтрокаСоединения, "Srvr") + НСтр(СтрокаСоединения, "Ref");
ЗаголовокHTTP.Вставить("Referer", СерверИсточник);
//Укажем формат данных Content-Type
ЗаголовокHTTP.Вставить("Content-Type", "multipart/form-data; boundary=" + Boundary);
//Укажем длину POST-запроса Content-Length
ФайлОтправки = Новый Файл(ИмяФайлаОтправки);
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());
ЗаголовокHTTP.Вставить("Content-Length", РазмерФайлаОтправки);
Инициализируем HTTPСоединение. При необходимости задаём параметры прокси.
Сервер = "www.some_site.ru"; //Естественно, следует указать свой адрес.
Порт = "80"; //Это общепринятый порт. Возможно, для вашего сервера применяется другой. Конкретное значение уточните у хостера.
//ИспользоватьПрокси - какая-то логическая переменная, может быть значение флажка на форме или переключатель
Если ИспользоватьПрокси Тогда
Прокси = Новый ИнтернетПрокси;
Прокси.НеИспользоватьПроксиДляЛокальныхАдресов = Истина;
Прокси.Пароль = "ПарольПрокси"; // укажите своё значение
Прокси.Пользователь = "ПользовательПрокси"; // укажите своё значение
НТТР = Новый HTTPСоединение(Сервер, Порт, , , Прокси);
Иначе
НТТР = Новый HTTPСоединение(Сервер, Порт);
КонецЕсли;
Собственно, отправка данных серверу.
АдресСкрипта = "some_script.php"; //Естественно, следует указать имя своего скрипта.
Попытка
НТТР.ОтправитьДляОбработки(ИмяФайлаОтправки, АдресСкрипта, ИмяФайлаОтвета, ЗаголовокHTTP);
Исключение
//Пример обработки ошибки соединения.
#Если Клиент Тогда
Сообщить("Неудачная попытка соединения: " + ОписаниеОшибки());
#Иначе
ЗаписьЖурналаРегистрации("HTTPСоединение", УровеньЖурналаРегистрации.Ошибка, , , "Неудачная попытка соединения: " + ОписаниеОшибки());
#КонецЕсли
Возврат;
КонецПопытки;
//Удалим файл отправки POST-запроса. Больше он нам не нужен.
УдалитьФайлы(ИмяФайлаОтправки);
Отправили данные, анализируем ответ сервера.
ФайлОтвета = Новый Файл(ИмяФайлаОтвета);
Если ФайлОтвета.Существует() Тогда
ТекстОтвета = Новый ТекстовыйДокумент();
ТекстОтвета.Прочитать(ИмяФайлаОтвета);
Если ТекстОтвета.КоличествоСтрок() > 0 Тогда
ОтветСервера = ТекстОтвета.ПолучитьТекст();
#Если Клиент Тогда
Сообщить(ОтветСервера);
#КонецЕсли
Иначе
#Если Клиент Тогда
Сообщить("Отправка файла на сервер: Получен пустой ответ сервера.");
#Иначе
ЗаписьЖурналаРегистрации("HTTPСоединение", УровеньЖурналаРегистрации.Ошибка, , , "Получен пустой ответ сервера.");
#КонецЕсли
КонецЕсли;
УдалитьФайлы(ИмяФайлаОтвета);
Иначе
#Если Клиент Тогда
Сообщить("Отправка файла на сервер: Ответ сервера не получен.");
#Иначе
ЗаписьЖурналаРегистрации("HTTPСоединение", УровеньЖурналаРегистрации.Ошибка, , , "Ответ сервера не получен.");
#КонецЕсли
КонецЕсли;
И наконец, примерное содержимое скрипта-приёмника данных на веб-сервере "some_script.php"
<?
//Читаем текстовые данные POST-запроса
$submit = ( isset($_POST['submit']) ) ? intval($_POST['submit']) : 0;
$some_field = ( isset($_POST['some_field']) ) ? htmlspecialchars($_POST['some_field']) : '';
//Проверим user-agent, хотя большого толку от такой проверки нет. См. ниже.
if ( $_SERVER['HTTP_USER_AGENT'] != '1C+Enterprise/8.1' )
{
@header('HTTP/1.0 403 Forbidden');
die('Hacking attempt');
}
if ( !empty($submit) )
{
//Здесь работаем с содержимым переданного файла.
$uploadFile = $_FILES['data'];
$tmp_name = $uploadFile['tmp_name'];
if ( !is_uploaded_file($tmp_name) )
{
die('Ошибка при загрузке файла');
}
else
{
//Считываем файл в строку
$data = file_get_contents($tmp_name);
//Декодируем данные
$data = base64_decode($data);
//Теперь нормальный файл можно сохранить на диске
$data_filename = $_FILES['data']['name'];
if ( !empty($data) && ($fp = @fopen($data_filename, 'wb')) )
{
@fwrite($fp, $data);
@fclose($fp);
}
unset($data);
}
}
?>
В завершение статьи процитирую.
Обращаю ваше внимание, что указанная здесь методика освещает возможность загрузки файлов на сервер. Использование их "в чистом виде" без доработки может быть небезопасным, и является потенциальной возможностью для взлома вашего сайта. А именно, отсутствие обработки имени файла, который пришел на сервер, отсутствие авторизации, определения источника, посылающего файл, может дать злоумышленнику возможность загрузить и выполнить вредоносный код на вашем сайте. Рассмотрение способов защиты не входит в данную статью и остается на ваше усмотрение.
Список использованной литературы:
Генерация HTTP запросов
_http://www.phpclub.ru/detail/article/http_request/
Загрузка на сервер нескольких файлов
_http://php.yar.ru/manual/ru/features.file-upload.multiple.php
Upload файла через ОтправитьДляОбработки, 1Сv8
_http://forum.codeby.net/index.php?showtopic=16780
Справочник по PHP : Советы : Как отправить файл на сервер
_http://www.spravkaweb.ru/php/sovet/putfile/
Сайт, для которого всё это реализовывалось
_http://agrosnabsklad.orenivolga.ru/
Взято с _http://infostart.ru/public/20017/