Передача файлов и данных на веб-сервер средствами 1С:Предприятие 8.X методом POST




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

73 Comments

  1. support

    Хорошая и полезная статья.

    Reply
  2. Serj1C

    А как отправить простой POST запрос без файла?

    Например, авторизация на infostart.

    Reply
  3. Поручик

    Вот так и отправить. Выкидываешь из файла отправки или содержимого POST-запроса лишнее, то что относится к двоичным данным или файлам, и отправляешь.

    Изучай матчасть по генерации HTTP запросов, ссылки я для чего дал?

    Reply
  4. Поручик

    От нечего делать, пока у нас сервер лежал, накатал обработку, иллюстрирующую пример POST-запроса без файлов.

    В качестве сайта — подопытного кролика выбран инфостарт

    Скачать http://forum.aeroion.ru/download.php?id=165

    Reply
  5. Serj1C

    (4) Спасибо, теперь можно изучать

    Reply
  6. ValentinV

    Почему таким сложным путем?

    Reply
  7. Поручик

    Лёгкие пути в студию. Про передачу по ftp знаю, не тот в данном случае путь.

    Reply
  8. мх

    Можно ли как-то передать файл на сервер из 7.7 ?

    Reply
  9. Поручик

    Можно. Только я от клюшек давно отошёл, забыл её как страшный сон, и даже искать что-то по ней неохота. Гугл вам поможет.

    Reply
  10. lsp71

    Спасибо за доходчивое объяснение

    Reply
  11. Gabi

    Спасибо вам большое за POST запрос.

    Но у меня не получается отправить этот POST запрос вроде сделала все как описано выше. Запрос доходит, но без файла.

    Все выглядит так :

    СодержимоеZIP = Base64Строка(Новый ДвоичныеДанные(АрхивФайлаZIP));

    ФайлОтправки = Новый ЗаписьТекста(ИмяФайлаОтправки, КодировкаТекста.ANSI, Символы.ПС, ЛОЖЬ);

    ФайлОтправки.ЗаписатьСтроку(«—» + Boundary);

    ФайлОтправки.ЗаписатьСтроку(«Content-disposition: form-data; name=»»key»»» + Символы.ПС);

    ФайлОтправки.ЗаписатьСтроку(«11111»);

    ФайлОтправки.ЗаписатьСтроку(«—» + Boundary);

    ФайлОтправки.ЗаписатьСтроку(«—» + Boundary);

    ФайлОтправки.ЗаписатьСтроку(«Content-Disposition: form-data; name=»»dump»»; filename=»»» + СчетчикВыгрузок+».zip» + «»»»);

    ФайлОтправки.ЗаписатьСтроку(«Content-Type: application/x-zip-compressed» + Символы.ПС + Символы.ПС);

    ФайлОтправки.ЗаписатьСтроку(СодержимоеZIP);

    ФайлОтправки.ЗаписатьСтроку(«—» + Boundary);


    ФайлОтправки.ЗаписатьСтроку(«—» + Boundary);

    ФайлОтправки.ЗаписатьСтроку(«Content-disposition: form-data; name=»»submit»»» + Символы.ПС);

    ФайлОтправки.ЗаписатьСтроку(«Загрузить»);

    ФайлОтправки.ЗаписатьСтроку(«—» + Boundary);

    ФайлОтправки.Закрыть();

    Пожалуйста помогите что не так?

    Reply
  12. Поручик

    Сделать именно так, как в примере формирования содержимого POST-запроса. Имейте в виду, этот код практически полностью приведён из рабочей конфигурации.

    Посмотреть содержимое массива $_FILES, $_POST на сервере.

    В конце концов, проверить размер передаваемых данных.

    Reply
  13. Mopnex03

    Ошибка работы с Интернет: server returned nothing (no headers, no data)

    Такая ошибка вылетает… В чем проблема? Код взят из этой статьи.

     Boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор()), «-«, «»);
    Содержимое = Base64Строка(Новый ДвоичныеДанные(Каталог+»upload.xml»));
    
    ИмяФайлаОтправки = Каталог+»post.txt»;
    ФайлОтправки = Новый ЗаписьТекста(ИмяФайлаОтправки, КодировкаТекста.ANSI, Символы.ПС, ЛОЖЬ);
    
    //Определяем раздел двоичных данных
    ФайлОтправки.ЗаписатьСтроку(«—» + Boundary);
    //Указываем имя файла для передачи
    ФайлОтправки.ЗаписатьСтроку(«Content-Disposition: form-data; name=»»uploadfile»»; filename=»»upload.xml»»»);
    //Указываем тип передаваемых данных.
    //С таким же успехом в Content-Type можно указать application/x-octet-stream
    ФайлОтправки.ЗаписатьСтроку(«Content-Type: application/octet-stream» + Символы.ПС + Символы.ПС);
    //Записываем кодированные двоичные данные
    ФайлОтправки.ЗаписатьСтроку(Содержимое);
    ФайлОтправки.ЗаписатьСтроку(«—» + Boundary);
    
    ФайлОтправки.Закрыть();
    
    //Формируем заголовок POST-запроса.
    
    ЗаголовокHTTP = Новый Соответствие();
    //Укажем формат данных Content-Type
    ЗаголовокHTTP.Вставить(«Content-Type», «multipart/form-data; boundary=» + Boundary);
    
    //Укажем длину POST-запроса Content-Length
    ФайлОтправки = Новый Файл(ИмяФайлаОтправки);
    РазмерФайлаОтправки = ФайлОтправки.Размер();
    ЗаголовокHTTP.Вставить(«Content-Length», РазмерФайлаОтправки);
    
    //Инициализируем HTTPСоединение. При необходимости задаём параметры прокси.
    
    НТТР = Новый HTTPСоединение(Сервер, Порт);
    
    //Собственно, отправка данных серверу.
    
    АдресСкрипта = «upload.php»; //Естественно, следует указать имя своего скрипта.
    Попытка
    НТТР.ОтправитьДляОбработки(ИмяФайлаОтправки, АдресСкрипта, Каталог+»upload.tmp», ЗаголовокHTTP);
    Исключение
    Сообщить(«Неудачная попытка соединения: » + ОписаниеОшибки());
    КонецПопытки;

    Показать

    Reply
  14. softmaker

    Пример реализации, используя, 1С:Предприятие 7.7 здесь.

    Reply
  15. FFelix

    Попробовал, работает. Спасибо! 🙂

    Reply
  16. Valerikk

    Здравствуйте.

    Возникла проблемка:

    если выполнять на стороне клиента, все нормуль;

    но если то же самое делать на стороне сервера (регл. заданием), приходит пустой ПОСТ на сервер 🙁 . ФайлОтправки и файл данных — идентичны.

    Посоветуйте, плиз, где искать косяк…

    Reply
  17. Поручик

    (16) Похожая проблема

    http://www.forum.mista.ru/topic.php?id=476078

    Ишите косяк или на веб-сервере или на сервере 1С, а то и на обоих.

    Reply
  18. tor0310
    Поручик пишет:

    Лёгкие пути в студию. Про передачу по ftp знаю, не тот в данном случае путь.

    Действительно, более легкие пути шли не туда. Этот работает. Спасибо

    Reply
  19. lena9push

    Отличная статья, спасибо!

    Единственное возник вопрос.

    Переводя текст в Base64 методом:

    СодержимоеZIP = Base64Строка(Новый ДвоичныеДанные(ИмяФайлаДанных));

    Как сделать обратное??

    Т.е. из Base64 перевести в исходный текст???

    Reply
  20. cool.vlad4

    (19)Base64Значение(СодержимоеZIP)…советую воспользоватся справкой в 1С

    Reply
  21. lena9push

    cool.vlad4, да, спасибо большое. Но на выходе будут двоичные данные, а их как преобразовать к исходнику?

    (извиняюсь за нубство, просто уже устала искать))

    Reply
  22. cool.vlad4

    (21) ДвоичныеДанные.Записать(ИмяФайла), да ничего страшного, я просто имею ввиду, что быстрее такие вопросы в поиске посмотреть, ведь все методы и свойства помнить невозможно. В конфигураторе нажимаете F1, вводите в поиске ДвоичныеДанные и находите ответ на свой вопрос. Также рекомендую использовать (если есть конфигурация, типовая к примеру) поиск по конфигурации и смотреть как это сделано там.

    Reply
  23. softest

    А как использовате Get метод

    Reply
  24. softest

    И как можно передать куки с одной сесии в другую или єто невозможно, или вытянуть куки из браузера?

    Reply
  25. ltfriend

    (24) softest, для работы с куки можно использовать WinHttpRequest

    как-то так (писалось на скорую руки, возможны ошибки, но смысл, думаю, понятен)

    Соединение = Новый COMОбъект(«WinHttp.WinHttpRequest.5.1»);
    Соединение.SetRequestHeader(«Cookie», «value1=abs;value2=xyz»);
    Соединение.Open(«GET», «www.mysite.com»);
    Соединение.Send();
    
    ЗаголовкиОтвета = Соединение.GetAllResponseHeaders();
    
    Cookie = Новый Структура;
    
    МассивЗаголовков = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(ЗаголовкиОтвета, Символы.ПС);
    
    Для каждого Заголовок Из МассивЗаголовков Цикл
    
    Если Лев(Заголовок, 11) = «Set-Cookie:» Тогда
    
    СтрокаCookie = СокрЛП(Сред(Заголовок, 12));
    Поз = Найти(СтрокаCookie, «=»);
    ИмяCookie = СокрЛП(Лев(СтрокаCookie, Поз-1));
    ЗначениеCookie = СокрЛП(Сред(СтрокаCookie, Поз+1));
    Cookie.Вставить(ИмяCookie, ЗначениеCookie);
    
    КонецЕсли;
    
    КонецЦикла;
    

    Показать

    Reply
  26. ltfriend

    А вообще можно файлы передавать как есть в виде двоичных данных с помощью процедуры «ОбъединитьФайлы»

    ИмяФайла1 = ПолучитьИмяВременногоФайла(«txt»);
    
    ЗаписьТекста = Новый ЗаписьТекста(ИмяФайла1);
    ЗаписьТекста.ЗаписатьСтроку(«—«+boundary);
    ЗаписьТекста.ЗаписатьСтроку(«Content-Disposition: form-data; name=»»file»»; filename=»»archive.zip»»»);
    ЗаписьТекста.ЗаписатьСтроку(«Content-Type: application/x-zip-compressed»);
    ЗаписьТекста.ЗаписатьСтроку(«»);
    ЗаписьТекста.Закрыть();
    
    ИмяФайла2 = ПолучитьИмяВременногоФайла(«txt»);
    
    ЗаписьТекста = Новый ЗаписьТекст(ИмяФайла2);
    ЗаписьТекста.ЗаписатьСтроку(«»);
    ЗаписьТекста.ЗаписатьСтроку(«—«+boundary+»—«);
    ЗаписьТекста.Закрыть();
    
    ИмяФайлаОтправки = ПолучитьИмяВременногоФайла(«out»);
    
    МассивФайлов = Новый Массив;
    МассивФайлов.Добавить(ИмяФайла1);
    МассивФайлов.Добавить(ИмяФайлаСДанными);
    МассивФайлов.Добавить(ИмяФайла2);
    
    ОбъединитьФайлы(МассивФайлов, ИмяФайлаОтправки);
    
    ….
    HTTP.ОтправитьДляОбработки(ИмяФайлаОтправки, «uploadfile.php», ИмяВходящегоФайла, Заголовки);
    ….
    

    Показать

    Reply
  27. Поручик

    (26) А вы пробовали? Данные точно попадают в массив $_FILES на сервере?

    Reply
  28. ltfriend

    (27) пробовал. И со своим сайтом. И на стену ВКонтакте таким способом картинки загружаются без проблем.

    Reply
  29. Поручик

    (28) Очень интересно. Знать бы этом когда делал проект или догадаться проверить. В этом случае статья могла и не появиться на свет.

    Reply
  30. vlad.frost

    Нужно ещё прокомментировать, как правильно формировать boundary в соответствии с RFC http://ru.wikipedia.org/wiki/MIME#.D0.9E.D1.80.D0.B3.D0.B0.D0.BD.D0.B8.D0.B7.D0.B0.D1.86.D0.B8.D1.8F_.D0.B4.D0.B0.D0.BD.D0.BD.D1.8B.D1.85

    Для передачи множественного сообщения в заголовок Content-Type добавляется параметр boundary (граница), который обозначает последовательность символов, разделяющих части сообщения. Граница может состоять из цифр, букв и символов «'()+_,-./:=?». При использовании специальных символов (не цифр и букв) значение параметра boundary следует заключать в двойные кавычки «»». Максимальная длина границы — 70 символов.

    Начало каждой части сообщения обозначается строкой «—boundary». Конец последнего сообщения обозначается строкой «—boundary—». Самые первые символы переноса строки CRLF (коды 13 и 10), которыми начинаются и заканчиваются пограничные строки не входят в содержимое самой части. Если за ними следуют ещё переносы строк, то они уже принадлежат включаемой части.

    В моём случае долго не получалось увидеть на стороне сервера что-либо в массиве $_FILES пока я не догадался вставить ещё один перенос строки в самое начало отправляемого файла (так называемая преамбула):

    Функция СформироватьФайлДляОтправки(ГраницаСекций)
    
    Попытка
    
    ИмяФайлаДляОтправки = ПолучитьИмяВременногоФайла(«xml»);
    ФайлОтправки = Новый ЗаписьТекста(ИмяФайлаДляОтправки );
    ФайлОтправки.ЗаписатьСтроку(«»); // <— вот она, недостающая строка
    ФайлОтправки.ЗаписатьСтроку(«—» + ГраницаСекций);
    ФайлОтправки.ЗаписатьСтроку(«Content-Disposition: form-data; name=»»userfile»»; filename=»»» + ИмяФайлаДляОтправки + «»»»);
    ФайлОтправки.ЗаписатьСтроку(«Content-Type: text/xml»);
    ФайлОтправки.ЗаписатьСтроку(«»);
    ФайлОтправки.ЗаписатьСтроку(ПолучитьДанные());
    ФайлОтправки.ЗаписатьСтроку(«—» + ГраницаСекций + «—«); // <— в конце обязательно указываем удвоенный дефис «—«, как предписывает стандарт
    
    ФайлОтправки.Закрыть();
    
    Исключение
    ЗаписьЖурналаРегистрации(«IGCDMS», УровеньЖурналаРегистрации.Ошибка, , ,
    «Не удалось сформировать файл для отправки: » + ОписаниеОшибки());
    Возврат «»;
    КонецПопытки;
    
    Возврат ИмяФайлаДляОтправки;
    
    КонецФункции
    

    Показать

    Reply
  31. borrman

    Спасибо большое за статью!

    Очень выручили!

    Есть, правда, вопрос:

    использование Base64 продиктовано тем, что данные могут содержать HTML-значимые символы? И я должен использовать кодирование base64 только в случае, если сервер производит декодирование, верно? Если же сервер этого не делает, то я могу отправлять текст файла как он в файле записан.

    (30)

    У меня заработало без первой пустой строки.

    Reply
  32. Поручик

    (31) В посте (26) написано, как обойтись без Base64.

    Reply
  33. borrman

    (32) Я использовал текстовый документ для получения текста.

    Reply
  34. Поручик

    Надо бы переработать статью с учетом рекомендаций.

    Reply
  35. Wrols

    При загрузке на сайт получал ошибку от ОтправитьДляОбработки Failed sending data to the peer.

    Оказалось, что проблема с параметром HTTP заголовка:

    ЗаголовокHTTP.Вставить(«Referer», СерверИсточник);

    Двое из трех хостингов плевали на этот параметр, а zenon выдавал упомянутую выше ошибку.

    Поручик, уберите этот параметр из статьи, чтоб другие не сталкивались с такой проблемой.

    Reply
  36. Поручик

    Статья переработана с учетом комментариев и приложена новая обработка с примерами отправки файла на сервер двумя способамии.

    Reply
  37. K0Tu

    Доброго дня. Информация очень интересна и полезна, спасибо автору. Но у меня возникает вопрос. Админ или программист на стороне сайта(я на стороне 1С программиста) требует от меня вставить в POST строку «pass=тут_пароль», куда конкретно вставить он не может сказать в заголовок ли в ФайлОтправки или еще куда. Подскажите, пожалуйста, куда этот реквизит вставить?

    Reply
  38. Поручик

    (37) В файл отправки. Пример смотрите в обработке, там всё есть.

    Reply
  39. lazorik

    Доброе время суток!

    я все прописываю как написано у вашей статье, но никак не получается отправить запрос, постоянно пустой POST массив отправляется… Можете помочь? Спасибо

    Reply
  40. Поручик

    (39) скачайте любую из приложенных обработок, они все рабочие.

    помощь платная.

    Reply
  41. lazorik

    Спасибо.Я попробовал пользоваться ваши обработки, но результат тот же.Может сталкивались с подобной проблемой, что пустой запрос отправляет?

    Reply
  42. vlad.frost

    (41) Обратите внимание на мой комментарий в этом обсуждении (30)

    Reply
  43. svilsa

    спасибо, очень нужная информация

    Reply
  44. Open-BS

    Коллеги, а с чем может быть связана ошибка

    Ошибка при вызове метода контекста (ОбъединитьФайлы): Ошибка сборки файла

    ОбъединитьФайлы(МассивФайловДляОбъединения, ИмяФайлаОтправки);

    по причине:

    Ошибка сборки файла

    по причине:

    Ошибка совместного доступа к файлу ‘C:UsersObrAppDataLocalTemp2v8_58C6_75.txt’

    Reply
  45. Поручик

    (44) Она может быть связана с ошибкой совместного доступа к файлу ‘C:UsersObrAppDataLocalTemp2v8_58C6_75.txt’

    Reply
  46. Open-BS

    (45) да я догадалась) А это было связано с тем, что был забыт метод ФайлОтправкиСередина.Закрыть(); Ну и в общем, если один из кусков собираемого файла не закрыт, его и объединить не получится, что логично.

    Reply
  47. kuza_87

    в 8.3 Механизм теперь другой. Нет примера обработки с механизмом на 8.3?

    Reply
  48. Поручик

    (47) Сделаю. Пятьсот рублей будет стоить.

    Reply
  49. kuza_87

    (48) Спасибо, уже сам сделал)))

    Reply
  50. Поручик

    Добавлена обработка для платформы 8.3. в режиме управляемого приложения

    Reply
  51. A2004333

    Мне пришлось добавить перевод строки перед Баундэри, который сразу за двоичными данными. После двоичных данных у меня больше никаких разделов не было, поэтому этот же Баундэри стал последним.

    Оригинальный код автора:

    ФайлОтправкиКонец.ЗаписатьСтроку(«—» + Boundary + «—«);

    Мой код:

    ФайлОтправкиКонец.ЗаписатьСтроку(Символы.ПС+»—» + Boundary + «—«);

    Большое спасибо автору за статью! Поставил плюс!

    Reply
  52. Поручик

    (51) Этот вариант статьи давно устарел, но заливать новый нет желания, так как двиг сайта курочит оформление по-своему, то есть вся работа под хвост. Новая версия находится на моём сайте.

    Reply
  53. Поручик

    Статья порядком устарела.

    Обновил обработку Отправка данных и загрузка файлов на веб-сервер 8.3.epf, в которой реализовано скачивание файлов с почти любого сайта, в том числе Google Drive, показаны методы работы с отсылкой и получением HTTP-заголовков, работа с перенаправлением (редиректом), кукисами (cookies) и некоторые другие. Всё для платформы 8.3.

    Reply
  54. Rustig

    (0) спасибо за столь обширное описание

    Reply
  55. Arc

    По мотивам статьи. Коротенькая функция, отправляющая файлы и данные через POST без создания временных файлов.

    Функция ХТТПЗапросПост(АдресСайта,АдресРесурса,ДанныеЗапроса)
    ТекстДляОтправки = «»;
    Boundary = Строка(Новый УникальныйИдентификатор());
    
    НомерФайла = 0;
    Для Каждого Элемент Из ДанныеЗапроса Цикл
    ТекстДляОтправки = ТекстДляОтправки + «—«+Boundary + Символы.ПС;
    Если ТипЗнч(Элемент.Значение) = Тип(«ДвоичныеДанные») Тогда
    НомерФайла = НомерФайла + 1;
    ТекстДляОтправки = ТекстДляОтправки + «Content-Disposition: form-data; name=»»file»+НомерФайла+»»»; filename=»»» + Элемент.Ключ + «»»» + Символы.ПС;
    ТекстДляОтправки = ТекстДляОтправки + «Content-Type: application/x-octet-stream» + Символы.ПС;
    Данные = Base64Строка(Элемент.Значение);
    Иначе
    ТекстДляОтправки = ТекстДляОтправки + «Content-Disposition: form-data; name=»»»+Элемент.Ключ+»»»» + Символы.ПС;
    Данные = Строка(Элемент.Значение);
    КонецЕсли;
    ТекстДляОтправки = ТекстДляОтправки + Символы.ПС;
    ТекстДляОтправки = ТекстДляОтправки + Данные + Символы.ПС;
    ТекстДляОтправки = ТекстДляОтправки + «—«+Boundary + Символы.ПС;
    КонецЦикла;
    Заголовки = Новый Соответствие();
    Заголовки.Вставить(«Content-Type», «multipart/form-data; boundary=» + Boundary);
    Заголовки.Вставить(«Content-Lenght», XMLСтрока(СтрДлина(ТекстДляОтправки)));
    Запрос = Новый HTTPЗапрос(АдресРесурса,Заголовки);
    Запрос.УстановитьТелоИзСтроки(ТекстДляОтправки, КодировкаТекста.ANSI);
    
    Попытка
    Соединение = Новый HTTPСоединение(АдресСайта);
    Возврат Соединение.ОтправитьДляОбработки(Запрос);
    Исключение
    Возврат Неопределено;
    КонецПопытки;
    КонецФункции
    

    Показать

    Пример вызова:

    Картинка = Номенклатура.ОсновноеИзображение.Хранилище.Получить();
    Если Картинка.Формат()<>ФорматКартинки.PNG Тогда
    Картинка.Преобразовать(ФорматКартинки.PNG);
    КонецЕсли;
    ИдентификаторНоменклатуры = Строка(Номенклатура.УникальныйИдентификатор());
    ИмяКартинки = Строка(ИдентификаторНоменклатуры)+».png»;
    
    ДанныеЗапроса = Новый Соответствие;
    ДанныеЗапроса.Вставить(ИмяКартинки,Картинка.ПолучитьДвоичныеДанные());
    ДанныеЗапроса.Вставить(«product_id»,ИдентификаторНоменклатуры);
    
    Ответ = ХТТПЗапросПост(«127.0.0.1″,»/update_image.php»,ДанныеЗапроса);
    Если Ответ<>Неопределено Тогда
    ТекстОтвета = Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.ANSI);
    ЭлементыФормы.ПолеHTML.УстановитьТекст(ТекстОтвета);
    Иначе
    Сообщить(«Нет связи с сайтом!!! Проверьте Ваше интернет соединение.»);
    КонецЕсли;
    

    Показать

    Reply
  56. ZhokhovM

    Поручик, запускаю вашу обработку «ПросмотрИнфостарт.epf», пишет:

    301 Moved Permanently

    ———————————————————————————

    nginx

    Есть ли обработка на управляемой форме или можешь доделать эту обработку если не сложно?

    Reply
  57. Поручик

    (56) Сдалась она тебе. Это давно устаревший вариант, чисто для примера.

    Reply
  58. ZhokhovM

    (58) ясно. Поищу её где-нибудь в другом месте с авторизацией.

    Reply
  59. FSerg

    Спасибо за публикацию!

    Отправить корректно двоичные данные (файл) на сервер получилось можно только через «ОбъединитьФайлы».

    Reply
  60. darkmessiahan

    (58) Зачем оставлять выложенные устаревшие варианты.

    Reply
  61. Поручик

    (61) Это исключительно абстрактные примеры, а не для практического использования.

    Reply
  62. Natali133

    Статья очень хорошая. Сколько будет стоить помощь в написании кода отправки данных из 1с на веб-серевер через post -запросы,а также комментарии по некоторым вопросам? Код необязательно , чтобы был рабочим, главное, чтобы он отражал всю логику передачи — нужен для курсовой работы.

    Reply
  63. Поручик

    (64) Так вот, в обработке всё рабочее и прокоментирована вся логика.

    Reply
  64. Mails79

    (39) lazorik,

    Уже наверно неактуально.

    В моём случае долго не получалось увидеть на стороне сервера что-либо в массиве $_FILES пока я не догадался вставить ещё один перенос строки в самое начало отправляемого файла (так называемая преамбула):

    ФайлОтправки.ЗаписатьСтроку(«»); // <— вот она, недостающая строка

    Reply
  65. Diversus

    (65) Сергей, скажите пожалуйста, у Вас есть замечательная функция:

    Код
    Функция ПолучитьСодержимоеВебАдреса(Знач СерверПриемник, Знач АдресСтраницы = "",
                    Знач ПараметрыСоединения = Неопределено, ЗаголовкиHTTP = Неопределено,
                    Знач ПолучитьКакДвоичныеДанные = Ложь, Знач ЗащищенноеСоединение = Ложь) Экспорт

    Показать полностью

    Но она работает для 1С версии 8.2.18 и выше. Есть ли аналог для устаревших версий 1С, это нужно для 8.2.13 🙁

    Вы используете рекурсивное получение для адресов, которые с кодами 301, 302.

    Может есть, что для моего случая?

    Спасибо.

    Reply
  66. Поручик

    (67) Разумеется нет. Я уже забыл про 8.2.

    Reply
  67. demon_infernal

    В обработке для 8.3 параметр Порт задан строкой, «80», что приводит к ошибке «Несоответствие типов». И изменить нельзя, на модуле пароль. Исправьте и выложите рабочую версию, либо версию без пароля на модуле.

    в управляемой форме все ок

    Reply
  68. Поручик

    (69) Выдернуть и сделать обработку для обычного приложения несколько минут.

    Reply
  69. piton66

    Ошибка работы с Интернет: server returned nothing (no headers, no data)

    Такая ошибка вылетает… В чем проблема?

    Reply
  70. Finn71

    Добрый день, а почему модуль объекта запоролен?

    Reply
  71. Поручик

    Там ничего интересного и практического нет.

    Reply
  72. Donpager

    С потоками тоже хорошо получается

    _разделитель = «—«+СтрЗаменить(Строка(Новый УникальныйИдентификатор()), «-«, «»);
    хедеры=Новый Соответствие;
    хедеры.Вставить(«Content-Type», «multipart/form-data; boundary=»+_разделитель);
    хПОСТ = Новый HTTPЗапрос(Ресурс,хедеры);
    _Поток = хПОСТ.ПолучитьТелоКакПоток();
    _Зап = Новый ЗаписьДанных(_Поток);
    _Зап.ЗаписатьСтроку(СтрШаблон(
    «—%1
    |Content-Disposition: form-data; name=»»image»»; filename=»»%2″»
    |Content-Type: image/%3
    |»,_разделитель,ИмяКартинки,МИМЕ));
    _Зап.Записать(ПолучитьИзВременногоХранилища(АдресХранения));
    _Зап.ЗаписатьСтроку(СтрШаблон(
    »
    |—%1—«,_разделитель));
    _Зап.Закрыть();
    
    Попытка
    хКон = Новый HTTPСоединение(срв);
    _Ответ = хКон.ОтправитьДляОбработки(хПОСТ);
    хКон = Неопределено;
    Исключение
    хКон = Неопределено;
    КонецПопытки;
    

    Показать

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *