helpf.pro
Регистрация
 +48 
Распечатать

Передача файлов и данных на веб-сервер из 1С методами GET и POST

При интеграции 1С с веб-сайтами всегда встает вопрос о передачи некоторых данных на веб-сервер. Будь то это передача параметров запроса для получения данных от веб-сервера в 1С или же передача данных из 1С, которые должны быть сохранены или каким-то образом обработаны на веб-сервере. Передаваться могут как простые данные в виде строк, чисел, так и целые файлы (изображения, XML-файлы и прочее). Для передачи и получения файлов и данных на веб-сервер в 1С используется объект HTTPСоединение.

Создание и инициализация HTTP соединения в 1С
Для инициализации HTTP соединения в 1С необходимо создать объект HTTPСоединение и в конструкторе указать параметры HTTP соединения.
Код 1C v 8.х
 Новый HTTPСоединение(<Сервер>, <Порт>, <ИмяПользователя>, <Пароль>, <Прокси>, <ЗащищенноеСоединение>)   


<Сервер> (обязательный) - адрес сервера, с которым необходимо установить соединение.
<Порт> (необязательный) - порт сервера, с которым устанавливается соединение.
Значение по умолчанию зависит от защищенности соединения (80 для незащищенного и 443 для SSL-соединения).
<ИмяПользователя> (необязательный) - имя пользователя на указанном сервере.
<Пароль> (необязательный) - пароль пользователя на указанном сервере.
<Прокси> (необязательный). Тип - ИнтернетПрокси. Прокси, используемый для соединения с сервером.
<ЗащищенноеСоединение> (необязательный). Тип - Булево. Определяет используемый протокол -
http или https. По умолчанию Ложь.
Ниже приведен примеры создания HTTPСоединения с сайтом http://www.mysite.ru/.
Код 1C v 8.х
 // соединение с параметрами по умолчанию
Соединение = Новый HTTPСоединение("www.mysite.ru");

// сервер использует порт 8080
Соединение = Новый HTTPСоединение("www.mysite.ru", 8080);

// сервер использует защищенное соединение (https),
// для подключения к серверу используется прокси
ПроксиСервер = Новый интернетПрокси;
ПроксиСервер.Пользователь = имяПользователя;
ПроксиСервер.Пароль = парольПользователя;

Соединение = Новый HTTPСоединение("www.mysite.ru",,,, ПроксиСервер, Истина);


Передача данных на веб-сервер из 1С методом GET.
Для передачи данных на веб-сервер из 1С методом GET используется процедура Получить() объекта HTTPСоединение.
Код 1C v 8.х
 Получить(<Источник>, <ИмяВыходногоФайла>, <Заголовки>)   


<Источник> (обязательный). Тип - Строка. Адрес ресурса на сервере.
<ИмяВыходногоФайла> (обязательный). Тип - Строка. Имя файла на диске, в который
помещаются данные, полученные от сервера (ответ сервера).
<Заголовки> (необязательный). Тип - Строка. Заголовки, добавляемые к запросу на сервер.
Текстовые пары вида <Заголовок>:<Значение>, разделенные комбинацией ВК + ПС.
(подробнее о заголовках будет сказано ниже).
Рассмотрим параметры процедуры Получить() более подробно:

В качестве источника указывается строка с адресом запроса, идущая после названия домена и символа "/". Так, если необходимо отправить данные на адрес https://www.mysite.com/getusers.php, то при создании HTTP соединения в конструкторе HTTPСоединение в поле "Сервер" указывается "www.mysite.com", признак защищенного соединения устанавливается в Истина, а в процедуре Получить() в параметре Источник указывается "getUsers.php".

В поле ИмяВыходногоФайла указывает имя файла на диске, в который будут сохранены данные, полученные от сервере в результате запроса. Так, например, если сервер возвращает список пользователей в формате XML, то на диск в указанный файл будет сохранен XML файл со списком пользователей.

О заголовках более подробно будет сказано ниже.

Так же, при запросе к веб-серверу зачастую передаются дополнительные данные (параметры) для этого запроса. Параметры от адреса источника отделяются символом "?". Каждый параметр задается в формате <Имя_Параметры>=<Значение_Параметры>. Параметры от адреса источника отделяются символом "?". Сами же параметры отделяются друг от друга символом "&". В результате строка адреса источника может выглядеть следующим образом: getUsers.php?owner_id=263544&count=100.

Ниже приведен пример, поясняющий все выше сказанное.
Код 1C v 8.х
 // необходимо выполнить запрос по адресу
// https://www.mysite.com/getUsers.php?owner_id=263544&amp;count=100
// ответ от сервера приходит в виде XML файла

имяВыходногоФайла = ПолучитьимяВременногоФайла("xml");

Соединение = Новый HTTPСоединение("www.mysite.com",,,,, Истина);
Соединение.Получить("getUsers.php?owner_id=263544&amp;count=100", имяВыходногоФайла);

ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(имяВыходногоФайла);

Пока ЧтениеXML.Прочитать() Цикл
// чтение ответа в виде XML файла
...
КонецЦикла;

ЧтениеXML.Закрыть();

// удаляем файл после использования
УдалитьФайлы(имяВыходногоФайла);


Заголовки HTTP
Ниже приведена общая информация о HTTP заголовках из википедии.

Заголовки HTTP (англ. HTTP Headers) — это строки в HTTP-сообщении, содержащие разделённую двоеточием пару имя-значение. Формат заголовков соответствует общему формату заголовков текстовых сетевых сообщений ARPA. Заголовки должны отделяться от тела сообщения хотя бы одной пустой строкой.

Все заголовки разделяются на четыре основных группы:

General Headers (рус. Основные заголовки) — должны включаться в любое сообщение клиента и сервера.
Request Headers (рус. Заголовки запроса) — используются только в запросах клиента.
Response Headers (рус. Заголовки ответа) — только для ответов от сервера.
Entity Headers (рус. Заголовки сущности) — сопровождают каждую сущность сообщения.
Именно в таком порядке рекомендуется посылать заголовки получателю.

Более подробно о заголовках HTTP можно прочитать здесь. Так же можно ознакомится со списком заголовков HTTP.

От себя лишь добавлю, что, если это явно не указано в требованиях к отправке данных веб-серверу заголовки HTTP для метода GET можно не указывать. Для метода POST обычно нужно указать заголовки Content-Type (тип передаваемых данных, например: "Content-Type: text/html;charset=utf-8") и Content-Length (размер передаваемых данных в байтах, например: "Content-Length: 1348").

Напомню, что HTTP заголовки в 1С указываются строкой в виде текстовых пар "<Заголовок>:<Значение>", разделенных комбинацией символов ВК+ПС.
Также заголовки можно задать типом Соответствие, где в качестве ключа указывается заголовок, а в качестве значения - значение заголовка.
Ниже приведены поясняющие примеры:
Код 1C v 8.х
 источник = "owner=263544&amp;count=100";

// Передача заголовков строкой
ЗаголовкиHTTP = "Content-Type:text/html;charset=utf-8" + Символ.ВК + Символ.ПС +
"Content-Length: "+СтрДлина(источник);
Соединение.Получить("", имяВыходногоФайла, ЗаголовкиHTTP);

// Вставить символы ВК+ПС можно и таким способом
ЗаголовкиHTTP = "Content-Type:text/html;charset=utf-8
|Content-Length: 1348";
Соединение.Получить("", имяВыходногоФайла, ЗаголовкиHTTP);

// Установка заголовков типом Соответствие
ЗаголовкиHTTP = Новый Соответствие;
ЗаголовкиHTTP.Вставить("Content-Type", "text/html;charset=utf-8");
ЗаголовкиHTTP.Вставить("Content-Length", СтрДлина(источник));

Соединение.Получить(источник, имяВыходногоФайла, ЗаголовкиHTTP);


Передача данных на веб-сервер из 1С методом POST.
Общие сведения.
Для передачи данных на веб-сервер из 1С методом POST используется процедура ОтправитьДляОбработки() объекта HTTPСоединение.
Код 1C v 8.х
 ОтправитьДляОбработки(<Источник>, <АдресРесурса>, <ИмяВыходногоФайла>, <Заголовки>)    

<Источник> (обязательный) - Имя файла-источника, который будет отправлен
на сервер для обработки.
<АдресРесурса> (обязательный). Тип - строка. Адрес ресурса на сервере,
в который посылаются данные из источника.
<ИмяВыходногФайла> (обязательный) - Имя файла на диске, в который записываются
полученные с сервера данные.
<Заголовки> (необязательный). Тип - строка. Заголовки, добавляемые к запросу на сервер.
Текстовые пары вида <Заголовок>:<Значение>, разделенные комбинацией ВК + ПС.
(подробнее о заголовках будет сказано ниже).
Рассмотрим параметры процедуры ОтправитьДляОбработки() подробнее:

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

Поле АдресРесурса аналогично полю Источник процедуры Получить(), т.е. указывается строка с адресом запроса, идущая после имени домена и символа "/".

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

О заголовках было упомянуто выше. Напомню лишь, что для метода POST обычно указываются заголовки Content-Type и Content-Length. В качестве параметра заголовка Content-Length указывается размер файла-источника, преобразованный с помощью функции XMLСтрока().

Ниже приведен пример, поясняющий все выше сказанное.
Код 1C v 8.х
 имяФайлаОтправки = "d:\data\request.txt"; // файл с отсылаемыми для обработки данными

// Определим размер файла-источника
// и установим HTTP заголовки
ФайлОтправки = Новый Файл(имяФайлаОтправки);
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());

Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "text/html;charset=utf-8");
Заголовки.Вставить("Content-Lenght", РазмерФайлаОтправки);

имяВыходногоФайла = ПолучитьимяВременногоФайла("xml");

Соединение = Новый HTTPСоединение("www.mysite.com");
Соединение.ОтправитьДляОбработки(имяФайлОтправки, "addPost.php", имяВыходногоФайла, Заголовки);


Передача параметров методом POST.
Для передачи параметров, аналогично методу GET, можно сформировать строку параметров, записать их в текстовый файл и отправить этот файл на сервер для обработки. Ниже приведен пример аналогичный примеру отправки методом GET, но теперь те же данные отправляются методом POST.
Код 1C v 8.х
 // сформируем файл для отправки на сервер

имяФайлаОтправки = ПолучитьимяВременногоФайла("txt");

ЗаписьТекста = Новый ЗаписьТекста(имяФайлаОтправки);
ЗаписьТекста.Записать("owner=263544&amp;count=100");
ЗаписьТекста.Закрыть();

// отправим файл на сервер для обработки

имяВыходногоФайла = ПолучитьимяВременногоФайла("xml"); // наш сервер возвращает ответы в виде XML

ФайлОтправки = Новый Файл(имяФайлаОтправки);
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());

Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "text/html;charset=utf-8");
Заголовки.Вставить("Content-Lenght", РазмерФайлаОтправки);

Соединение = Новый HTTPСоединение("www.mysite.com");
Соединение.ОтправитьДляОбработки(имяФайлОтправки, "addPost.php", имяВыходногоФайла, Заголовки);

// удалим файл отправки - он больше не нужен
Попытка
УдалитьФайлы(имяФайлаОтправки);
Исключение
КонецПопытки;

// обработаем ответ сервера

ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(имяВыходногоФайла);

Пока ЧтениеXML.Прочитать() Цикл
// чтение ответа в виде XML файла
...
КонецЦикла;

ЧтениеXML.Закрыть();

// удаляем файл после использования
Попытка
УдалитьФайлы(имяВыходногоФайла);
Исключение
КонецПопытки;



Передача файлов методом POST.
Зачастую данные для обработки задаются не виде строки параметров разделенных "&", как в рассматриваемых выше примерах, а виде файла определенного формата, например XML или JSON. Рассмотрим пример отправки данных на веб-сервер для обработки методом POST, которые задаются в формате XML. Например, сервер может добавить ваш комментарий к материалу. В описании процедуры добавлении сказано, что данные необходимо отправлять по адресу www.mysite.com/addComment.php. Сами данные должны быть переданы в следующем виде:
Код
<?xml version="1.0" encoding="UTF-8"?>
<request>
<user_id>ID_Пользователя</user_id>
<post_id>ID_Материала</post_id>
<message>Текст_Комментария</message>
</request>

где:
<ID_Пользователя> - id пользователя на сайте, от имени которого добавляется комментарий;
<ID_Материала> - id материала на сайте, к которому добавляется комментарий;
<Текст_Комментария> - текст комментария.

Предположим, что нам уже известны id пользователя и материала и они хранятся в переменных user_id и post_id. Ниже приведен пример, решающий нашу задачу.
Код 1C v 8.х
 // подготовим файл с данными для отправки
имяФайлаОтправки = ПолучитьимяВременногоФайла("xml");

ОбъектXML = Новый ЗаписьXML;
ОбъектXML.ОткрытьФайл(имяФайлаОтправки, "UTF-8");
ОбъектXML.ЗаписатьОбъявлениеXML();
ОбъектXML.ЗаписатьБезОбработки(
"<request>
| <user_id>" + user_id + "</user_id>
| <post_id>" + post_id + "</post_id>
| <message>" + ТекстКомментария + "</message>
|</request>");
ОбъектXML.Закрыть();

// отправим файл на сервер для обработки

имяВыходногоФайла = ПолучитьимяВременногоФайла("xml"); // наш сервер возвращает ответы в виде XML

ФайлОтправки = Новый Файл(имяФайлаОтправки);
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());

Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "text/html;charset=utf-8");
Заголовки.Вставить("Content-Lenght", РазмерФайлаОтправки);

Соединение = Новый HTTPСоединение("www.mysite.com");
Соединение.ОтправитьДляОбработки(имяФайлОтправки, "addComment.php", имяВыходногоФайла, Заголовки);

// удалим файл отправки - он больше не нужен
Попытка
УдалитьФайлы(имяФайлаОтправки);
Исключение
КонецПопытки;

// обработаем ответ сервера

ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(имяВыходногоФайла);

Пока ЧтениеXML.Прочитать() Цикл
// чтение ответа в виде XML файла
...
КонецЦикла;

ЧтениеXML.Закрыть();

// удаляем файл после использования
Попытка
УдалитьФайлы(имяВыходногоФайла);
Исключение
КонецПопытки;


Загрузка файлов (изображений, документов и т.п.) на веб-сервер методом POST.
Зачастую возникает необходимость загрузки файлов на веб-сервер. Это может быть, например, изображение к статье на сайте, или фотография для альбома, или архив для файлообменника. Ранее мы рассматривали передачу методом POST параметров или просто файлов. Таким же образом можно и передавать двоичные файлы. Но как быть, если файлы необходимо отправлять вместе с параметрами? Для возможности отправки файлов в этом случае используется HTTP заголовок ContentType:multipart/form-data. Следует заметить, что обычно таким способом передаются файлы через веб-браузеры. Т.е. когда на сайте вы выбираете файл и нажимаете кнопку "Загрузить", то файл передается способом описанным ниже. При таком способе сам файл также задается как переменная, т.е., например, файл передается через параметр file или image. Однако, мы не можем просто передать file=<Двоичные_Данные>. А вот как все таки передать файл мы и рассмотрим ниже.

Для возможности вместе с параметрами передавать и двоичные данные (файлы) необходимо сформировать HTTP заголовок Content-Type следующим образом:
Content-Type: multipart/form-data, boundary=<уникальные_данные>
где <уникальные_данные> - это любой набор цифр и/или символов, который будет служить для отделения значений друг от друга. Значение boundary должно быть уникальным в пределах пересылаемой информации, т.е. таких символов не должно встречаться в пересылаемых файлах и переменных.

Bounday можно сформировать, например, таким образом
Код 1C v 8.х
 boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");   


Все данные отделяются друг от друга разделителем boundary. Начинать разделитель нужно с "--":
Код
--<boundary>
Content-Disposition: form-data; name="<имя_переменной>"
<пустая_строка>
<значение_переменной>
Для отправки файла необходимо еще добавить тип и имя файла:

--<boundary>
Content-Disposition: form-data; name="<имя_переменной>"; filename="<имя_файла>"
Content-Type: <тип_файла> (например image/jpeg или text/plain)
<пустая_строка>
<данные_файла>

В конце данных нужно закрыть разделитель, добавили в конце разделителя "--", т.е. вид будет "--<boundary>--".

Итак, например, нам нужно передать на веб-сервер текстовый файл через параметр "text", его описание через параметр "desc" и id пользователя через параметр "uid", для которого будет загружен наш файл.

Предположим, что файл содержит следующий текст:
Мороз и солнце; день чудесный!
Еще ты дремлешь, друг прелестный -
Пора, красавица, проснись:
Открой сомкнуты негой взоры
Навстречу северной Авроры,
Звездою севера явись!

Описание должно содержать "Стих А.С. Пушкина", а id пользователя равно "0123456". Тогда файл должен быть сформирован следующим образом (для упрощения предположим, что bounday мы уже сформировали и он равен "ccf8111910")
Код
--ccf8111910
Content-Disposition: form-data; name="uid"

0123456
--ccf8111910
Content-Disposition: form-data; name="desc"

Стих А.С. Пушкина
--ccf8111910
Content-Disposition: form-data; name="text"; filename="stih.txt"
Content-Type: text/plain

Мороз и солнце; день чудесный!
Еще ты дремлешь, друг прелестный -
Пора, красавица, проснись:
Открой сомкнуты негой взоры
Навстречу северной Авроры,
Звездою севера явись!
--ccf8111910--

А теперь перейдем непосредственно к 1С. Пусть у нас будет форма с реквизитами "Пользователь", "Описание" и "ИмяФайла". Реализуем отправку данных, описанным выше способом
Код 1C v 8.х
 // подготовим файл с данными для отправки
имяФайлаОтправки = ПолучитьимяВременногоФайла("txt");
Boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");

ЗаписьТекста = Новый ЗаписьТекста(имяФайлаОтправки);

// параметр "uid"
ЗаписьТекста.ЗаписатьСтроку("--"+boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""uid""");
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.ЗаписатьСтроку(Пользователь);

// параметр "desc"
ЗаписьТекста.ЗаписатьСтроку("--"+boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""desc""");
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.ЗаписатьСтроку(Описание);

// параметр "text"
ФайлДляПередачи = Новый ТекстовыйДокумент;
ФайлДляПередачи.Прочитать(имяФайла);

ЗаписьТекста.ЗаписатьСтроку("--"+boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""text""; filename=""stih.txt""");
ЗаписьТекста.ЗаписатьСтроку("Content-Type: text/plain");
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.Записать(ФайлДляПередачи.ПолучитьТекст());
ЗаписьТекста.ЗаписатьСтроку("");

// закроем разделитель
ЗаписьТекста.ЗаписатьСтроку("--"+boundary+"--");

ЗаписьТекста.Закрыть();

ФайлОтправки = Новый Файл(имяФайлаОтправки);
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());

// передадим данные на сервер
Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "multipart/form-data, boundary="+boundary);
Заголовки.Вставить("Content-Lenght", РазмерФайлаОтправки);

Соединение = Новый HTTPСоединение("www.mysite.com");
Соединение.ОтправитьДляОбработки(имяФайлОтправки, "postFile.php", имяВыходногоФайла, Заголовки);


Передача текстовых файлов таким способом проблем не вызывает. Сложнее дело обстоит с файлами, содержащими двоичные данные (изображения, архивы и т.п.). Все дело в том, что в 1С просто нет методов для чтение двоичных файлов в строку. Если мы делаем обмен со своим сайтом, которые сами и разрабатывали, то можно просто преобразовать файл в строку Base64 при помощи процедуры Base64Строка(), а на стороне сервера преобразовать строку Base64 обратно.
Код 1C v 8.х
 // подготовим файл с данными для отправки
имяФайлаДанных = "d:\photo\birthday.jpg";

имяФайлаОтправки = ПолучитьимяВременногоФайла("txt");
Boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");

ЗаписьТекста = Новый ЗаписьТекста(имяФайлаОтправки);

// параметр "file"
ЗаписьТекста.ЗаписатьСтроку("--"+boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""file""; filename=""photo.jpg""");
ЗаписьТекста.ЗаписатьСтроку("Content-Type: image/jpeg");
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.Записать(Base64Строка(Новый ДвоичныеДанные(имяФайлаДанных)));
ЗаписьТекста.ЗаписатьСтроку("");

// закроем разделитель
ЗаписьТекста.ЗаписатьСтроку("--"+boundary+"--");

ЗаписьТекста.Закрыть();

ФайлОтправки = Новый Файл(имяФайлаОтправки);
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());

// передадим данные на сервер
Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "multipart/form-data, boundary="+boundary);
Заголовки.Вставить("Content-Lenght", РазмерФайлаОтправки);

Соединение = Новый HTTPСоединение("www.mysite.com");
Соединение.ОтправитьДляОбработки(имяФайлОтправки, "uploadFile.php", имяВыходногоФайла, Заголовки);


А как же быть если мы загружаем файл на сторонний сервер, который принимает файл как есть без преобразование его в строку Base64(). В это случае можно пойти на хитрость. В 1С есть процедура ОбъединитьФайлы(), которая объединяет несколько файлов на диске в один результирующий файл
Код 1C v 8.х
 ОбъединитьФайлы(<ИменаЧастей>, <ИмяРезультирующегоФайла>)   

<ИменаЧастей> (обязательный). Тип - Массив. Массив имен частей файлов, которые
требуется объединить. Объединение будет происходить в порядке, в котором заданы
имена файлов в массиве.
<ИмяРезультирующегоФайла> (обязательный). Тип - Строка. Имя файла, который будет
создан в результате объединения файлов.
Т.е. мы можем сформировать текстовый файл с запросом, объединить его с файлом(-ами), которые необходимо передать на веб-сервер и передать уже файл, получившийся в результате объединения исходных файлов. Ниже демонстрируется процесс передачи двух zip архивов на сервер с дополнительными параметрами user_id и post_id.
Код 1C v 8.х
 // подготовим файлы с данными для отправки

массивФайлов = Новый Массив;

Boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");

имяФайлаСПараметрами = ПолучитьимяВременногоФайла("txt"); // первый файл, содержащий параметры

ЗаписьТекста = Новый ЗаписьТекста(имяФайлаСПараметрами);

// параметр "user_id"
ЗаписьТекста.ЗаписатьСтроку("--"+boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""user_id""");
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.ЗаписатьСтроку(user_id);

// параметр "post_id"
ЗаписьТекста.ЗаписатьСтроку("--"+boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""post_id""");
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.ЗаписатьСтроку(post_id);

// начало параметра "file1"
ЗаписьТекста.ЗаписатьСтроку("--"+boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""file1""; filename=""archive1.zip""");
ЗаписьТекста.ЗаписатьСтроку("Content-Type: application/x-zip-compressed");
ЗаписьТекста.ЗаписатьСтроку("");

ЗаписьТекста.Закрыть(); // заканчиваем работу с файлом 1

массивФайлов.Добавить(имяФайлаСПараметрами); // добавляем 1-ый файл для объединения
массивФайлов.Добавить(имяФайлаАрхива1); // добавляем 1-ый архив для объединения

// второй файл параметров, содержаший начало параметра "file2"
имяФайлаСПараметрами = ПолучитьимяВременногоФайла("txt");

ЗаписьТекста = Новый ЗаписьТекста(имяФайлаСПараметрами);

// начало параметра "file2"
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.ЗаписатьСтроку("--"+boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""file2""; filename=""archive2.zip""");
ЗаписьТекста.ЗаписатьСтроку("Content-Type: application/x-zip-compressed");
ЗаписьТекста.ЗаписатьСтроку("");

ЗаписьТекста.Закрыть(); // заканчиваем работу с файлом 2

массивФайлов.Добавить(имяФайлаСПараметрами); // добавляем 2-ой файл для объединения
массивФайлов.Добавить(имяФайлаАрхива2); // добавляем 2-ой архив для объединения

ЗаписьТекста.Записать(ФайлДляПередачи.ПолучитьТекст());
ЗаписьТекста.ЗаписатьСтроку("");

// третий файл, закрывающий параметры
имяФайлаСПараметрами = ПолучитьимяВременногоФайла("txt");

ЗаписьТекста = Новый ЗаписьТекста(имяФайлаСПараметрами);

ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.ЗаписатьСтроку("--"+boundary+"--");

ЗаписьТекста.Закрыть(); // заканчиваем работу с файлом 3

массивФайлов.Добавить(имяФайлаСПараметрами); // добавляем 3-ий файл, закрывающий параметры

// результирующий файл, который и будет отправлен
имяФайлаОтправки = ПолучитимяВременногоФайла("out");

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

ФайлОтправки = Новый Файл(имяФайлаОтправки);
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());

// передадим данные на сервер
Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "multipart/form-data, boundary="+boundary);
Заголовки.Вставить("Content-Lenght", РазмерФайлаОтправки);

Соединение = Новый HTTPСоединение("www.mysite.com");
Соединение.ОтправитьДляОбработки(имяФайлОтправки, "postFile.php", имяВыходногоФайла, Заголовки);


Ну вот, вроде бы, и все, что я хотел рассказать о способах передачи файлов и данных на веб-сервер из 1С. Если что-то не понятно, что-то хотите уточнить или нашли ошибки - пишите в комментариях.
Автор: Павел
Разместил:   Версии: | 8.x |  Дата:   Прочитано: 199060
 +48 
Распечатать
Возможно, вас также заинтересует
Как заполнить табличную часть формы программно? 8
Нужно по кнопке Заполнить - сформировать данные для заполнения табличных частей и заполнить их. Форма имеет вид: Рядом с кнопкой Записать и закрыть добавлена кнопка Заполнить документ , код ее команды: // Код заполнения ТЧ НаСервере П
10060 (0x0000274C): Попытка установить соединение была безуспешной 24
Установили новый терминальный сервер, на нем подняли 1С, терминальные пользователе неописуемо довольны, все просто летает :) И вот же надо было такому случиться, главному бухгалтеру не понравилось работать через терминал, а еще у нее свой ноутбук и
17 правил для составления оптимального ЗАПРОСа к данным базы 1С 52
Для формирования и выполнения запросов к таблицам базы данных в платформе 1С используется специальный объект языка программирования Запрос . Создается этот объект вызовом конструкции Новый Запрос . Запрос удобно использовать, когда требуется получ
1C и Google Maps 21
была поставлена задача отображения на географической карте медицинских учреждений. После обзора предлагаемых решений был выбран сервис google. Но так же подобного рода подход будет работать и с картами сервиса yandex. Во время решения задачи было реш
1C медленно работает по сети с базой на SQL Server 22
Данное обстоятельство может быть обусловлено многими причинами. Одна из них - неоптимальная настройка MS SQL . Перечислим неоптимальности в настройке: 1) Неправильно указанный сетевой протокол, используемый для взаимодействия 1С с SQL Server. П
Посмотреть все результаты поиска похожих
Комментарии
harmless
23.02.2013 14:37Комментарий: 9
harmless
Преогромное спасибо!
IKSparrow
11.02.2013 11:36Комментарий: 8
IKSparrow
Вкратце - получаете поток средствами PHP, разбираете и пишите в СУБД, например.
IKSparrow
11.02.2013 11:34Комментарий: 7
IKSparrow
Ну вот вам пример обработки XML-файла с контрагентами на стороне сервера:

Код VBS
 
<?php session_start();
require_once dirname(__FILE__) . '/../inc/initf.php' ;
class Onec_Import_Customers {
private static $instance ;
function __construct(){

self::$instance = $this ;

}

public function process () {
$rawHttp = file_get_contents( 'php://input' ) ;
$xml_raw = str_replace("xml=", '', $rawHttp) ;

if ($_SESSION['loggedin'] || true){
file_put_contents('log/onec_import_customers_' .time(). '.log', 'REQUEST ' . print_r($_REQUEST, 1) . ' SERVER ' . print_r($_SERVER,1). ' FILES ' . print_r($_FILES,1) . $xml_raw ) ;
file_put_contents('log/onec_import_customers_last.log', 'REQUEST ' . print_r($_REQUEST, 1) . ' SERVER ' . print_r($_SERVER,1). ' FILES ' . print_r($_FILES,1) . $xml_raw ) ;

//$xml = stripslashes($_POST['xml']);
$xml = stripslashes($xml_raw);
if(!$xml) {
$xml = $xml_raw ;
//die ('no XML data (post key "xml")') ;
}
if ($this->setCustomers($xml)) {
die ('OK');
} else {
die ('FAIL') ;
}
} else {
die ();
}
}

private function setCustomers($xml){
$db = db::getInstance() ;

$sxml = simplexml_load_string($xml) ;

$customers = $sxml->{'Договор'} ? $sxml->{'Договор'} : self::err( 'Invalid file format. Customers.') ;

$final = array () ;
$k = 0 ;

$allCustomers = array () ;

foreach ($customers as $cust) {
$password = base::generatePassword(6,1) ;

$arr ['password'] = $password ;

$arr ['email'] = (array)$cust->{'Почта'} ;//? (array)$cust->{'Почта'} : self::err( 'Invalid file format. Customer no:' . $k . '. Invalid email') ;
$arr ['email'] = $arr ['email'][0] ? $arr ['email'][0] : '';//: self::err( 'Invalid file format. customer no:' . $k . '. Invalid email') ;

$arr ['app_name'] = (array)$cust->{'Наименование'} ;//? (array)$cust->{'Наименование'} : self::err( 'Invalid file format. Customer no:' . $k . '. Invalid name') ;
$arr ['app_name'] = $arr ['app_name'][0] ? $arr ['app_name'][0] : '';//self::err( 'Invalid file format. customer no:' . $k . '. Invalid name') ;

$arr ['clientid'] = (array)$cust->{'Номер'} ? (array)$cust->{'Номер'} : self::err( 'Invalid file format. Customers no:' . $k . '. Invalid clientid') ;
$arr ['clientid'] = $arr ['clientid'][0] ? $arr ['clientid'][0] : self::err( 'Invalid file format. Customers no:' . $k . '. Invalid clientid') ;

$arr ['date'] = (array)$cust->{'Дата'} ? (array)$cust->{'Дата'} : self::err( 'Invalid file format. Customers no:' . $k. '. Invalid date') ;
$arr ['date'] = $arr ['date'][0] ? $arr ['date'][0] : self::err( 'Invalid file format. Customers no:' . $k . '. Invalid date' ) ;

$arr ['date'] = explode(".",$arr ['date']);
krsort($arr ['date']);
$arr ['date'] = implode("-",$arr ['date']) . ' 00:00:00' ;

$arr ['phone_home'] = (array)$cust->{'Телефон'} ;//? (array)$cust->{'Телефон'} : self::err( 'Invalid file format. Customers no:' . $k . '. Invalid phone') ;
$arr ['phone_home'] = $arr ['phone_home'][0] ? $arr ['phone_home'][0] : '';//self::err( 'Invalid file format. Customers no:' . $k . '. Invalid phone') ;

$arr ['district'] = (array)$cust->{'Район'} ;//? (array)$cust->{'Район'} : self::err( 'Invalid file format. Customers no:' . $k . '. Invalid district') ;
$arr ['district'] = $arr ['district'][0] ? $arr ['district'][0] : '';//self::err( 'Invalid file format. Customers no:' . $k . '. Invalid district') ;

$arr ['street'] = (array)$cust->{'Улица'} ;//? (array)$cust->{'Улица'} : self::err( 'Invalid file format. Customers no:' . $k . '. Invalid street') ;
$arr ['street'] = $arr ['street'][0] ? $arr ['street'][0] : '';//self::err( 'Invalid file format. Customers no:' . $k . '. Invalid street') ;

$arr ['building'] = (array)$cust->{'Дом'} ;//? (array)$cust->{'Дом'} : self::err( 'Invalid file format. Customers no:' . $k . '. Invalid building') ;
$arr ['building'] = $arr ['building'][0] ? $arr ['building'][0] : '' ;//self::err( 'Invalid file format. Customers no:' . $k . '. Invalid building') ;

$arr ['apartament'] = (array)$cust->{'Квартира'} ;//? (array)$cust->{'Квартира'} : self::err( 'Invalid file format. Customers no:' . $k . '. Invalid apartament') ;
$arr ['apartament'] = $arr ['apartament'][0] ? $arr ['apartament'][0] : '';// self::err( 'Invalid file format. Customers no:' . $k . '. Invalid apartament') ;

$allCustomers [$arr ['clientid']]= array('password'=>$password, 'email'=>$arr ['email']) ;

$final []= $arr ;
++$k ;
}

return $this->buildCustomers($final) ;
/*
if($this->buildCustomers($final)) {
foreach ($allCustomers as $clientid=>$data) {
self::sendPasswordToMail($data['email'], $clientid, $data['password']) ;
}
}*/



}

private static function sendPasswordToMail($email, $client_id, $password) {
$db = db::getInstance() ;
$config = config_model::getInstance() ;
$lng = Request::$currentLang['id'] ;
$email_text = $db->getRow('s1_text', '*', "`alias`='registration_ok' AND `lng_id`='{$lng}'") ;
$body = str_replace('%password%', $password, $email_text['content']) ;
$body = str_replace('%client_id%', $client_id, $body) ;
base::mailSend($body, $email_text['title'] . " - " . $config->defaultTitle('site.ru') , $email, $app['app_name'], $config->site_admin_mail('info@site.ru'), $config->from_name('site')) ;

}

private function buildCustomers ($data) {

$db = db::getInstance() ;


$qry = 'I_nsert INTO s1_customer (`active`,`password`,`app_name`,`email`,`date`,`clientid`,`phone_home`,`street`, `district`, `building`, `apartament`) VALUES ' ;
foreach ($data as $rows){
$queryArr []= "(
'0'
,MD5('{$rows['password'>')
,'{$db->escape($rows['app_name'])}'
,'{$db->escape($rows['email'])}'
,'{$db->escape($rows['date'])}'
,'{$db->escape($rows['clientid'])}'
,'{$db->escape($rows['phone_home'])}'
,'{$db->escape($rows['street'])}'
,'{$db->escape($rows['district'])}'
,'{$db->escape($rows['building'])}'
,'{$db->escape($rows['apartament'])}'
)" ;
}
$qry .= implode(',', $queryArr) ;
$qry .= ' ON DUPLICATE KEY UPDATE
`app_name` = VALUES(app_name)
,`date` = VALUES(date)
,`email` = VALUES(email)
,`phone_home` = VALUES(phone_home)
,`street` = VALUES(street)
,`district` = VALUES(district)
,`building` = VALUES(building)
,`apartament` = VALUES(apartament)
' ;
return $db->query($qry) ;
}

public static function getInstance(){
if (!self::$instance)
{
new self() ;
}
return self::$instance ;

}

private static function err($msg) {
throw new ImportException($msg) ;
}

}

class ImportException extends Exception {

function __construct ($msg) {
die ('Error : ' . $msg ) ;
}

}

IKSparrow
11.02.2013 11:30Комментарий: 6
IKSparrow
Всё, прошу прощения, ступил =) Понял, что требуется.
IKSparrow
11.02.2013 11:10Комментарий: 5
IKSparrow
Немного непонятно, какой скрипт вы хотите видеть, если данные на HTTP сервер передаются методом POST. Например, сделать это можно таким образом:
Код 1C v 8.2 УП
 
WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
WinHttp.SetTimeouts(30000, 30000, 70000, 70000);
WinHttp.Option(2,"Windows-1251");
WinHttp.Open("POST", "http://site.ru" + /index.php?query=customers",0);

WinHttp.SetRequestHeader("Accept-Language", "ru");
WinHttp.SetRequestHeader("Accept-Charset", "utf-8");
WinHttp.setRequestHeader("Content-Language", "ru");
WinHttp.setRequestHeader("Content-Charset", "utf-8");
WinHttp.setRequestHeader("Content-Type", "multipart/form-data");

РР= Новый ТекстовыйДокумент;
РР.Прочитать(ИмяФайлаВыгрузки);

ПараметрыПОСТ = "xml=" + РР.ПолучитьТекст();
WinHttp.Send(ПараметрыПОСТ);


А обработку данных, должен выполнить принимающий сервер.
E_Migachev
09.02.2013 18:47Комментарий: 4
E_Migachev
sergey_fedorov, автор пропал... боюсь что уже не увидим скрипт, может выложит кто? *17
sergey_fedorov
09.02.2013 13:00Комментарий: 3
sergey_fedorov
А скрипта как не было так нет!!!
harmless
29.01.2013 09:37Комментарий: 2
harmless
Присоединяюсь к предыдущему посту. Если не трудно выложите скрипт.
Mishgan
14.11.2012 09:08Комментарий: 1
Mishgan
А вы не могли бы разместить пример скрипта на php для приема данных файлов на стороне сервера
Вы не можете отправить комментарий анонимно, пожалуйста войдите или зарегистрируйтесь.