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




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

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

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

<?php // Полная загрузка сервисных книжек, создан 2026-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 не будет опубликован. Обязательные поля помечены *