Приветствую,
пишу для разработчиков большей частью, к сожалению, не могу выложить полное решение, но сервис загрузки со стороны принимающей стороны универсален (создан расширением, и использует стандартный БСП механизм работы с дополнительными обработками и отчетами).
На создании сервиса, я останавливаться не буду, на ресурсе вполне хватает информации. Первая проблема с какой я столкнулся это, как Передать файл сервису. На "Инфостарте" к сожалению подходящего примера не нашел , но несколько идей мне подкинула обработка которая разбирала НТТП-запрос как поток (Полезно), в другой я взял мысль о передаче двоичных данных в файле.
Что получилось:
мФайл = новый Файл(ПараметрыЗапроса.ПолноеИмяФайла);
ИмяФайла = мФайл.Имя;
//Сведения о обработке
ПараметрыРегистрации = новый Структура("ЭтоОтчет,ИмяФайла,АдресДанныхОбработки");
ПараметрыРегистрации.ЭтоОтчет = ВРег(Прав(ИмяФайла,3))="ERF";
ПараметрыРегистрации.ИмяФайла = ИмяФайла;
ПараметрыРегистрации.АдресДанныхОбработки = ПоместитьВоВременноеХранилище(новый ДвоичныеДанные(ПутьФайла));
//Адрес сервиса
HTTPЗапрос = Новый HTTPЗапрос("/"+ПараметрыЗапроса.ИмяБазы+"/hs/load1c/obj/");
Boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");
// передадим данные на сервер
HTTPЗапрос.Заголовки.Вставить("Content-Type" , "multipart/form-data");
HTTPЗапрос.Заголовки.Вставить("boundary" , boundary);
HTTPЗапрос.Заголовки.Вставить("fileName" , ИмяФайла);
HTTPЗапрос.Заголовки.Вставить("report" , Формат(ПараметрыРегистрации.ЭтоОтчет,"БЛ=Ложь; БИ=Истина"));
HTTPЗапрос.Заголовки.Вставить("name_1c_Object" , ПараметрыРегистрации.Наименование);
//Формирование тела запроса
// параметр "file"
имяФайлаОтправки = ПолучитьимяВременногоФайла("txt");
ЗаписьТекста = Новый ЗаписьТекста(имяФайлаОтправки,КодировкаТекста.UTF8);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""file""; filename="""+ИмяФайла+"""");
ЗаписьТекста.ЗаписатьСтроку("Content-Type: binary");
ЗаписьТекста.ЗаписатьСтроку("start_"+Boundary);
ЗаписьТекста.Записать(Base64Строка(Новый ДвоичныеДанные(ПутьФайла)));
ЗаписьТекста.ЗаписатьСтроку("end_"+Boundary);
ЗаписьТекста.Закрыть();
HTTPЗапрос.УстановитьИмяФайлаТела(имяФайлаОтправки);
HTTPОтвет = Соединение.ОтправитьДляОбработки(HTTPЗапрос);
ТелоОтвета = СокрЛП(HTTPОтвет.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8));
Если не ПустаяСтрока(ТелоОтвета) Тогда
Сообщить( ТелоОтвета);
КонецЕсли;
Если HTTPОтвет.КодСостояния = 200 Тогда
Сообщить("ок");
Иначе
Сообщить("Ошибка отправки запроса");
КонецЕсли;
данный пример выполняется на клиенте, для себя я определил это правило, но можно конечно и на сервер отправить,
Для начала я описываю (заголовки запроса, Имя файла, тип обработки, Имя регистрации в базе, а также переменую boundary)
boundary - Уникальный идентификатор, который служит ключом начало и конца будущего тела запроса
Дальше, создаем текстовый файл для тела запроса, первый абзац это служебная информация, дальше мы кодируем в Base64 наши двоичные данные и встраиваем в файл, обрамляя "тегами" начала и конца.
После устанавливаем полученных текстовый файл в тело запроса и отправляем для обработки.
На стороне отправителя мы закончили.
Далее со стороны ХТТП сервиса
типовая функция обработки запроса:
Функция uploadpost(Запрос)
СтруктураОтвета = ПоместитьВХранилищеФайлИзТелаСтрокиХТТП(Запрос);
ЗагрузитьОбъект1С_в_спр_допОбработок(СтруктураОтвета);
Если ПустаяСтрока(СтруктураОтвета.ОписаниеОшибок) Тогда
Ответ = Новый HTTPСервисОтвет(200);
иначе
Ответ = Новый HTTPСервисОтвет(500,СтруктураОтвета.ОписаниеОшибок);
Ответ.УстановитьТелоИзСтроки(СтруктураОтвета.ОписаниеОшибок, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
КонецЕсли;
Возврат Ответ;
КонецФункции
Функция ПоместитьВХранилищеФайлИзТелаСтрокиХТТП(Запрос)
СтруктураОтвета = Новый Структура("ИмяФайла,АдресХранилища,ОписаниеОшибок,ЭтоОтчет,ИмяОбъекта");
СтруктураОтвета.ИмяФайла = Запрос.Заголовки.Получить("fileName");
СтруктураОтвета.ЭтоОтчет = ?(Запрос.Заголовки.Получить("report")="Истина",Истина,Ложь);
СтруктураОтвета.ИмяОбъекта = Запрос.Заголовки.Получить("name_1c_Object");
boundary = Запрос.Заголовки.Получить("boundary");
РазмерФайла = Запрос.Заголовки.Получить("Content-Lenght");
Если ЗначениеЗаполнено(СтруктураОтвета.ИмяФайла) и ЗначениеЗаполнено(boundary) Тогда
ОписаниеОшибки = "";
ТелоСтрока = Запрос.ПолучитьТелоКакСтроку();
МаркерНачала = "start_"+Boundary;
ДлиннаМаркера1 = СтрДлина(МаркерНачала);
ПозицияНачала = СтрНайти(ТелоСтрока,МаркерНачала)+ДлиннаМаркера1+1;
МаркерОкончания = "end_"+Boundary;
ПозицияОкончания= СтрНайти(ТелоСтрока,МаркерОкончания);
ТелоФайла = Сред(ТелоСтрока,ПозицияНачала,ПозицияОкончания-ПозицияНачала);
Попытка
СтруктураОтвета.АдресХранилища = ПоместитьВоВременноеХранилище(Base64Значение(ТелоФайла));
Исключение
ОписаниеОшибки = ОписаниеОшибки+ОписаниеОшибки();
КонецПопытки;
СтруктураОтвета.ОписаниеОшибок = ОписаниеОшибки;
КонецЕсли;
Возврат СтруктураОтвета;
КонецФункции
Процедура ЗагрузитьОбъект1С_в_спр_допОбработок(СтруктураЗадания)
УстановитьПривилегированныйРежим(Истина);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ДополнительныеОтчетыИОбработки.Ссылка КАК Ссылка
|ИЗ
| Справочник.ДополнительныеОтчетыИОбработки КАК ДополнительныеОтчетыИОбработки
|ГДЕ
| ДополнительныеОтчетыИОбработки.Наименование = &Наименование";
Запрос.УстановитьПараметр("Наименование", СтруктураЗадания.ИмяОбъекта);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
ХД = Новый ХранилищеЗначения(ПолучитьИзВременногоХранилища(СтруктураЗадания.АдресХранилища));
Если ВыборкаДетальныеЗаписи.Следующий() Тогда
СО = ВыборкаДетальныеЗаписи.ссылка.ПолучитьОбъект();
со.ХранилищеОбработки = ХД;
со.Версия = формат(ТекущаяДата(),"ДФ=dd/MM/yy");
СО.Записать();
Иначе
СтруктураЗадания.ОписаниеОшибок = "Не найдено в доп.обработках: <"+СтруктураЗадания.ИмяОбъекта+">"
КонецЕсли;
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры
тут следует сказать, что я просто помещаю в хранилище данных обработку, согласен, что немного топорно без проверки, можно использовать СведенияОВнешнейОбработке.
Тестирование:
- Платформа (8.3.12.1685)
- Бухгалтерия предприятия, редакция 3.0 (3.0.71.83)