Имя: Пароль:
1C
1С v8
Хелп! Мерцающая ошибка при отправке файла через HTTP
,
0 Alex87r
 
02.07.19
08:46
Всем привет!
Есть такой код для выгрузки файла из 1С через HTTP
Сейчас возникает проблема при отправке файла PDF - скана договора.
Т.е. файл не выгружается на сервер. Если я этот файл пересохраню в пдф через DoPDF, то он прекрасно выгружается.
Или например запакую в архив, то тоже выгружается.
Так же отправлю этот файл через postman - он отправляется без ошибок.
Т.е. ошибка в том, что 1С как то неправильно формирует файл запроса для HTTP с подобными файлами. Т.е. все сканы договоров не отправляются.
И что не так с файлом или 1С?
Может быть в тело запроса добавляется какой то символ неправильный?


Процедура ВыгрузитьИЗПамятиНаСервере()
    
    Сервер = Сервер;
    Подключение = Новый Структура ("HTTP, ЗаголовокHTTP, Адрес" );    
    Подключение.Адрес = "v1/requests.uploadFile?requestNb=НомерЗаявки&fileCatId=ИДФайла";
    Подключение.Адрес = СтрЗаменить(Подключение.Адрес,"НомерЗаявки", "784-N77");
    Подключение.Адрес = СтрЗаменить(Подключение.Адрес,"ИДФайла", "2");    
    
    HTTP = Новый HTTPСоединение(Сервер,,,,,,Новый ЗащищенноеСоединениеOpenSSL);    
    
    Сообщение = СоздатьСообщение();        
    
    HHTPЗапрос = Новый HTTPЗапрос(Подключение.Адрес, Сообщение.Заголовки);    
    HHTPЗапрос.УстановитьТелоИзДвоичныхДанных(Сообщение.Тело);
    
    Сообщение.Тело.Записать("C:\temp.txt");
    
    HTTPОтвет = HTTP.ОтправитьДляОбработки(HHTPЗапрос);
    ТекстОтвета = HTTPОтвет.ПолучитьТелоКакСтроку();
    Сообщить(ТекстОтвета);
    
    
КонецПроцедуры

&НаКлиенте
Процедура ВыгрузитьИЗПамяти(Команда)
    ВыгрузитьИЗПамятиНаСервере();
КонецПроцедуры

Функция СоздатьСообщение()

        // Формируем основное составное сообщение
        Разделитель = СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-","");
        Файл1 = СоздатьСообщение_Изображение("file", "C:\1.pdf", "C:\1.pdf", Разделитель);
        Результат = Новый Структура();
        Заголовки = Новый Соответствие();
        Результат.Вставить("Заголовки", Заголовки);
        Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + разделитель);
        Заголовки.Вставить("authorization", authorization);    
        Тело = Новый ПотокВПамяти();
        ЗаписьДанных = Новый ЗаписьДанных(Тело);              
        ЗаписьДанных.Записать(Файл1);
        ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель);
        ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель + "--");
        ЗаписьДанных.Закрыть();
        ДанныеТела = Тело.ЗакрытьИПолучитьДвоичныеДанные();
        Результат.Вставить("Тело", ДанныеТела);
        Возврат Результат;
КонецФункции
    

// Возвращается HTTP-сообщение в виде ДвоичныеДанные
Функция СоздатьСообщение_Изображение(ИмяСообщения, ИмяФайла, Картинка, Разделитель)      
        Поток = Новый ПотокВПамяти();
        ЗаписьДанных = Новый ЗаписьДанных(Поток);
        // Заголовки
        ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель);

        ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""file""; filename=""C:\1.pdf""");
        ЗаписьДанных.ЗаписатьСтроку("");
        // Тело
        ЗаписьДанных.Записать(Новый ДвоичныеДанные(Картинка));
        ЗаписьДанных.Закрыть();
        
        Возврат Поток.ЗакрытьИПолучитьДвоичныеДанные();
КонецФункции

Запрос, при котором файл не выгружается https://yadi.sk/d/A9NoV480kJnL9g
Запрос, при котором файл выгружается https://yadi.sk/d/tVGaVBdpI65yvg
1 Cyberhawk
 
02.07.19
09:03
Вроде разделитель через ==, а не через --
2 Cyberhawk
 
02.07.19
09:04
Ну и ошибку-то конечно же надо написать
3 Alex87r
 
02.07.19
09:12
(2) Ошибка: "Файл не загружен. Проверьте запрос и обратитесь к документации"
(1) У меня как раз с разделителем -- работает.
4 Cyberhawk
 
02.07.19
09:23
Ну тогда дело вот в этом: ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель);
        ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель + "--");
5 Широкий
 
02.07.19
09:26
(3) Если ты настолько умный - вопросы то зачем задавать?
6 Alex87r
 
02.07.19
09:26
(4) Почему? Другие файлы отправляются с такой конструкцией
7 Alex87r
 
02.07.19
09:27
(5) Спс за совет.
8 Широкий
 
02.07.19
09:29
(7) Сорян. Не правильно понял.
Почему не "УстановитьИмяФайлаТела"?
9 Alex87r
 
02.07.19
09:33
(8) У меня запрос сохранен в оперативной памяти в виде двоичных данных. Т.е. я файл запроса не сохраняю на жесткий диск.
Это если бы файл с запросом был сохранен на жестком диске, то УстановитьИмяФайлаТела(ПутьКФайлу)
10 Cyberhawk
 
02.07.19
09:35
А вот ты заголовки сначала вставляешь в структуру, а потом наполняешь их. Может надо наоборот?
11 Alex87r
 
02.07.19
09:38
(10) Не, они в структуру добавляются, с этим все норм. Специально по отладке глянул
12 Alex87r
 
02.07.19
09:46
Немного переделал код, пакую файл в архив.
Теперь он успешно загружается. А почему пдф без архива не грузится, как это объяснить?


Функция СоздатьСообщение_Изображение(ИмяСообщения, ИмяФайла, Картинка)      
        Поток = Новый ПотокВПамяти();
        ЗаписьДанных = Новый ЗаписьДанных(Поток);
      
// Заголовки
        ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""file""; filename=""C:\1.pdf""");
        ЗаписьДанных.ЗаписатьСтроку("");
        // Тело    
        АдресАрхива = Новый ПотокВПамяти();    
        НовыйАрхив = Новый ЗаписьZipФайла(
            АдресАрхива,
            "", // пароль на архив (оставим пустой)
            "", // комментарий к архиву
            МетодСжатияZIP.Сжатие, // сжатие или копирование
            УровеньСжатияZIP.Оптимальный,
            МетодШифрованияZIP.Zip20
        );
        НовыйАрхив.Добавить(Картинка);
        НовыйАрхив.Записать();
        
        //ЗаписьДанных.Записать(Новый ДвоичныеДанные(Картинка));
        ЗаписьДанных.Записать(АдресАрхива.ЗакрытьИПолучитьДвоичныеДанные());

        ЗаписьДанных.Закрыть();
        
        Возврат Поток.ЗакрытьИПолучитьДвоичныеДанные();
КонецФункции
13 Широкий
 
02.07.19
09:56
https://its.1c.ru/db/metod8dev#content:5917:hdoc

Возьми отсюда готовую функцию

ЗаписьДанных = Новый ЗаписьДанных(Тело);              
ЗаписьДанных.Записать(Файл1);
ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель);  <<<-- Мне кажется это лишнее
ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель + "--");
14 Alex87r
 
02.07.19
10:01
(13) Спс, я как раз оттуда брал и переделал немного) Не, это не лишнее. Другие файлы с ней отправляются же
15 Alex87r
 
02.07.19
10:15
Открываю файл, который не отправляется через программу BECYPDFMETAEDIT, заполнил производителя.

https://yadi.sk/i/gEhrUsS1vQa2LA

О чудо, файл отправляется. Очищаю производителя - тоже отправляется. Беру исходный файл, пытаюсь отправить - ошибка.
16 Alex87r
 
02.07.19
10:15
Какая то жесть
17 zva
 
02.07.19
10:44
Ну из символов только BOM напрашивается. Можно попробовать в ЗаписьДанных = Новый ЗаписьДанных(Поток); явно кодировку указать "CESU-8"
А так можно сравнивать выходной файл из 1с с проблемным pdf и после шаманства с записью и очисткой производителя у этого же файла.
18 Alex87r
 
02.07.19
10:51
(17) Указал кодировку   ЗаписьДанных = Новый ЗаписьДанных(Поток, "CESU-8"); - не помогло.
А что за BOM?
Попробую поискать, чем файлы отличаются.
19 Alex87r
 
02.07.19
11:08
В косячном файле нет такой секции в конце файла:


38 0 obj
<<
/Contents 40 0 R
/CropBox [ 0 0 595.08 841.68 ]
/MediaBox [ 0 0 595.08 841.68 ]
/Parent 33 0 R
/Resources 39 0 R
/Rotate 0
/Type /Page
>>
endobj
29 0 obj
<<
/Contents 31 0 R
/CropBox [ 0 0 595.08 841.68 ]
/MediaBox [ 0 0 595.08 841.68 ]
/Parent 33 0 R
/Resources 30 0 R
/Rotate 0
/Type /Page
>>
endobj
35 0 obj
<<
/CreationDate (D:20190315085538Z)
/Creator (Win)
/ModDate (D:20190702115838+05'00')
/Producer (Win)
>>
endobj

xref
29 1
0003181764 00000 n
35 1
0003181921 00000 n
38 1
0003181607 00000 n

trailer
<<
/ID [ <01C5469D9251347094DFC353EFEFA834> <80FFE24B2B0522DF5AC15D8DAE3D51EF> ]
/Info 35 0 R
/Prev 116
/Root 37 0 R
/Size 43
>>
startxref
3182044
%%EOF

38 0 obj
<<
/Contents 40 0 R
/CropBox [ 0 0 595.08 841.68 ]
/MediaBox [ 0 0 595.08 841.68 ]
/Parent 33 0 R
/Resources 39 0 R
/Rotate 0
/Type /Page
>>
endobj
29 0 obj
<<
/Contents 31 0 R
/CropBox [ 0 0 595.08 841.68 ]
/MediaBox [ 0 0 595.08 841.68 ]
/Parent 33 0 R
/Resources 30 0 R
/Rotate 0
/Type /Page
>>
endobj
35 0 obj
<<
/CreationDate (D:20190315085538Z)
/ModDate (D:20190702115958+05'00')
/Producer (Win)
>>
endobj

xref
29 1
0003182444 00000 n
35 1
0003182601 00000 n
38 1
0003182287 00000 n

trailer
<<
/ID [ <01C5469D9251347094DFC353EFEFA834> <455EC71FC05F758FE3F795980A55BF8E> ]
/Info 35 0 R
/Prev 3182044
/Root 37 0 R
/Size 43
>>
startxref
3182709
%%EOF

38 0 obj
<<
/Contents 40 0 R
/CropBox [ 0 0 595.08 841.68 ]
/MediaBox [ 0 0 595.08 841.68 ]
/Parent 33 0 R
/Resources 39 0 R
/Rotate 0
/Type /Page
>>
endobj
29 0 obj
<<
/Contents 31 0 R
/CropBox [ 0 0 595.08 841.68 ]
/MediaBox [ 0 0 595.08 841.68 ]
/Parent 33 0 R
/Resources 30 0 R
/Rotate 0
/Type /Page
>>
endobj
35 0 obj
<<
/CreationDate (D:20190315085538Z)
/ModDate (D:20190702120856+05'00')
>>
endobj

xref
29 1
0003183113 00000 n
35 1
0003183270 00000 n
38 1
0003182956 00000 n

trailer
<<
/ID [ <01C5469D9251347094DFC353EFEFA834> <E8208C6036C445AB19225848FEB3862B> ]
/Info 35 0 R
/Prev 3182709
/Root 37 0 R
/Size 43
>>
startxref
3183362
%%EOF
Программист всегда исправляет последнюю ошибку.