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

Хранилище

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

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



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

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

Некоторое время назад в ходе реализации одного проекта потребовалось организовать автоматическую передачу данных на веб-сервер посредством регламентного задания.
Покопавшись прежде всего в мануалах, синтаксис-помощнике 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 Текстовая версия Сейчас: 25.06.25, 21:37
1С Предприятие 8.3, 1С Предприятие 8.2, 1С Предприятие 8.1, 1С Предприятие 8.0, 1С Предприятие 7.7, Литература 1С, Общие вопросы по администрированию 1С, Методическая поддержка 1С - всё в одном месте: на Украинском 1С форуме!