Заказы на доработку 1С (сервис удаленной работы)

Хранилище

База знаний
Бесплатные отчеты, обработки, конфигурации, внешние компоненты для 1С Статьи, описание работы, методики по работе с 1С

Здравствуйте, гость ( Вход | Зарегистрироваться )



> Передача файлов и данных на веб-сервер средствами 1С:Предприятие 8.1 методом POST          
Vofka Подменю пользователя
сообщение 05.10.09, 13:26
Сообщение #1

У нас здесь своя атмосфера...
***********
Группа: Основатель
Сообщений: 13948
Из: Киев
Спасибо сказали: 4514 раз
Рейтинг: 3635.6

Некоторое время назад в ходе реализации одного проекта потребовалось организовать автоматическую передачу данных на веб-сервер посредством регламентного задания.
Покопавшись прежде всего в мануалах, синтаксис-помощнике 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/

Не нашли ответа на свой вопрос?
Зарегистрируйтесь и задайте новый вопрос.


Ответить Новая тема
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

RSS Текстовая версия Сейчас: 28.03.24, 15:07
1С Предприятие 8.3, 1С Предприятие 8.2, 1С Предприятие 8.1, 1С Предприятие 8.0, 1С Предприятие 7.7, Литература 1С, Общие вопросы по администрированию 1С, Методическая поддержка 1С - всё в одном месте: на Украинском 1С форуме!