Имя: Пароль:
1C
 
Отладка http-запроса из Postman
0 Никулин Леонид
 
27.06.24
15:39
Добрый день!

Есть HTTP-сервис. По условию задачи есть сторонняя база, которая будет обращаться к моему HTTP-сервису и получать ответ. В теле запроса JSON и произвольное количество файлов. Есть на ИТСе готовый пример https://its.1c.ru/db/metod8dev/content/5917/hdoc Взял его и в 1С сделал тестовую отправку запроса самому себе. отправляю. Получаю. Запрос читается. Всё ок.
Теперь тот же запрос нужно отправить из Постмена. Отправляю. Получаю. Читаю заголовки и тело. Алгоритм тот же. С заголовками всё норм, а вот с телом беда. Тело передаю как двоичные данные. Вот оно упорно не хочет читаться((
Может я где-то с настройками постмена косячу? Если есть соображения буду рад.

Спасибо.
1 Смотрящий
 
27.06.24
15:40
Тело перед отправкой в base64 загоняй
2 n0ther
 
27.06.24
15:46
(1) магистр йода в посте
3 Никулин Леонид
 
27.06.24
15:48
(1) из 1С у меня без этого работает. Ну да ладно. А как это делается в постмене?
4 Смотрящий
 
27.06.24
15:49
(3) "перед отправкой" из твоего http-сервиса
5 Никулин Леонид
 
27.06.24
15:57
Возможно плохо описал проблему. Попробую еще раз. Я отправляю из Постмена запрос. На стороне постмена не знаю как кодировать тело в base64. На стороне http-сервиса получаю запрос и читаю тело. Тут бяка при чтении. Не совсем Вас понял. Опишите, пожалуйста, чуть более подробно что нужно сделать?
6 Смотрящий
 
27.06.24
15:59
На стороне постмана ничего делать не надо.
В сервисе оберни в json твоем Двоичные данные в Base64Строка
7 Никулин Леонид
 
27.06.24
16:01
А понял. Ну в примерах нигде так не делают просто. Попробую. Спасибо за комментарий!
8 OldCondom
 
27.06.24
16:09
9 Никулин Леонид
 
27.06.24
16:16
Всё же ума у меня не хватает. Я могу конечно из ДвоичныхДанных получить строку в формате Base64, но что с ней дальне делать? Не соображу. Покажу код на стороне сервиса при чтении запроса. Так будет более наглядно:

&НаСервере
Функция ПрочитатьСообщение(Тело, Разделитель)
    
    //Тело - ДвоичныеДанные
    //Разделитель - Строка с разделителем
    
    Маркеры = Новый Массив();
    Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("==" + Разделитель));
    Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("==" + Разделитель + Символы.ПС));
    Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("==" + Разделитель + Символы.ВК));
    Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("==" + Разделитель + Символы.ВК + Символы.ПС));
    Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("==" + Разделитель + "=="));
        
    текст = Неопределено;
    изображение1 = Неопределено;
    изображение2 = Неопределено;
    
    Стр = Base64Строка(Тело);    //и что с этим делать? ЧтениеДанных работает с ДвоичнымиДанными
    
    ЧтениеДанных = Новый ЧтениеДанных(Тело);
    ЧтениеДанных.ПропуститьДо(Маркеры);
    ОбщийБуферДвоичныхДанных = ЧтениеДанных.ПрочитатьВБуферДвоичныхДанных();
    БуферыДвоичныхДанных = ОбщийБуферДвоичныхДанных.Разделить(Маркеры);
    
    СтруктураРаспознанногоСообщения = Новый Структура;
    Сч = 1;
    Для Каждого Буфер Из БуферыДвоичныхДанных Цикл

        Поток = новый ПотокВПамяти(Буфер);
        ЧтениеЧасти = Новый ЧтениеДанных(Поток);
        ДД = ЧтениеЧасти.Прочитать().ПолучитьДвоичныеДанные();
        Если ДД.Размер() = 0 Тогда
            Продолжить;    //Вот сюда попадаю((
        КонецЕсли;    
        СтруктураРаспознанногоСообщения.Вставить("ФайлВариантДва" + Сч, ДД);
        Сч = Сч + 1;
    
        ЧтениеЧасти.Закрыть();
        Поток.Закрыть();
        
    КонецЦикла;
    
    Для Каждого ДД Из СтруктураРаспознанногоСообщения Цикл
        ДД.Значение.Записать("E:\Путь к файлу\" + ДД.Ключ);
    КонецЦикла;
    
КонецФункции
10 Никулин Леонид
 
27.06.24
16:20
(8) информативно. Я вообще не так делаю. Ща попробую...
11 Никулин Леонид
 
27.06.24
16:42
(8) У меня в теле запроса JSON и картинка. Это добро разделено Разделителем. Вот тело запроса если сделать ПолучитьТелоКакСтроку():

----------------------------959821427642407330468393
Content-Disposition: form-data; name="improvementRequest"
Content-Type: application/json

{
"improvementRequest": {
"author": {
"phoneNumber": "+79991569033",
"telegramId": 562306003,
"firstName": "Иван",
"lastName": "Иванов",
"middleName": "Иванович"
},
"organisation": "ТК «СОЛНЕЧНЫЙ ДАР»",
"ideaVector": "Безопасность",
"problem": "В теплицах не носят каски",
"idea": "Контролировать ношение касок",
"appearanceOfEconomicEffect": "true"
}
}
----------------------------959821427642407330468393
Content-Disposition: form-data; name="files"; filename="У.jpg"; filename*=UTF-8''%D0%A3.jpg
Content-Type: image/jpeg

���� JFIF  H H  �� C        !"$"$�� �J�*Fs�*UV#�Q�a� ���Í����^�!�!|�N�ҞUc�=}9�Rc��N�i

(вот тут кусок текста выкинул т.к. сильно длинный файл)

��JI�K�׮|��&1�u��|� j���R�s�V � ��
----------------------------959821427642407330468393--


И я если тело переведу в строку потом ЧтениемJSON это дело не прочитаю.
Как я понимаю (и как на ИТСе и в подобных примерах сделано) нужно получать тело именно как двоичные данные. И потом читать
12 Никулин Леонид
 
27.06.24
16:44
В постмене тело оформлено вот так
13 Никулин Леонид
 
27.06.24
17:08
up.
(8) Дело в том, что при отправке запроса именно из постмена тело формируется не в том виде как указано в статье. В том всё и дело
14 Никулин Леонид
 
27.06.24
17:41
up
15 Garikk
 
27.06.24
17:52
попробуй покопать в сторону поля Content-Disposition, там много чего бывает разного
и form-data и attachment и у всего пакета общего может быть mixed а не form-data
на этом бывают парсеры спотыкаются у разных сервисов
16 novichok79
 
27.06.24
20:56
(11) у тебя мультипарт вообще, судя по телу запроса.
надо вычитать разные части, и взять ту, что у тебя JSON.
17 Никулин Леонид
 
28.06.24
08:12
(16) Да мультипарт. Он тоже читается как двоичные данные и  разбивается Разделителем на части на сколько я понял. А можно чуть подробнее описать текстом как это делается? Или примерчик с кодом. Буду премного благодарен
18 rozer76
 
28.06.24
11:54
19 Никулин Леонид
 
28.06.24
12:50
Спасибо за комментарий! Посмотрел ссылочку. Нам можно подсмотреть примеры как формировать и передавать запросы. А мне нужно на стороне сервиса получать и читать. Боюсь не мой случай.
20 Никулин Леонид
 
01.07.24
18:56
Пишу ответ сам себе. Сто пудов кому-то пригодиться. В моём случае кодировать/расколировать строку в base64 не нужно. Постмен это не делает. И на стороне сервиса при чтении это тоже не нужно. Ошибка как всегда оказалась крайне банальна. В примере из ИТСа (ссылка в первом сообщении) и других примерах разделитель формируется из строки по формату: "==" + Разделитель. В моём случае Постмен с какого-то перепуга формировал разделитель в формате: "--" + Разделитель. В результате двоичные данные не удавалось разбить по корявому разделителю на блоки. Решение. Для совместимости добавил в массив разделителей новые разделители. На всякий случай добавляю получившийся код. При необходимости конечно нужно адаптировать под свою задачу. Еще раз. Это на стороне http-сервиса при чтении полученного запроса:
21 Никулин Леонид
 
01.07.24
18:59
Функция ПрочитатьСообщение4(тело, Разделитель)
    
    //Тело - двоичные данные
    //Разделитель - Строковый разделитель
    
    Маркеры = Новый Массив();
    Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("==" + Разделитель));
    Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("==" + Разделитель + Символы.ПС));
    Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("==" + Разделитель + Символы.ВК));
    Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("==" + Разделитель + Символы.ВК + Символы.ПС));
    Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("==" + Разделитель + "=="));
    Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("--" + Разделитель));
    Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("--" + Разделитель + Символы.ПС));
    Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("--" + Разделитель + Символы.ВК));
    Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("--" + Разделитель + Символы.ВК + Символы.ПС));
    Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("--" + Разделитель + "--"));
    
    
    ТаблицаФайлов = Новый ТаблицаЗначений;
    ТаблицаФайлов.Колонки.Добавить("ДвоичныеДанные");
    ТаблицаФайлов.Колонки.Добавить("ИмяФайла");
    ТаблицаФайлов.Колонки.Добавить("Расширение");        
    
    ЧтениеДанных = Новый ЧтениеДанных(тело);
    ЧтениеДанных.ПропуститьДо(Маркеры);
    
    ОбщийБуферДвоичныхДанных = ЧтениеДанных.ПрочитатьВБуферДвоичныхДанных();
    БуферыДвоичныхДанных = ОбщийБуферДвоичныхДанных.Разделить(Маркеры);
    Для Каждого Буфер Из БуферыДвоичныхДанных Цикл
        
        Поток = новый ПотокВПамяти(Буфер);
        ЧтениеЧасти = Новый ЧтениеДанных(Поток);
        ЗаголовкиЧасти = ПрочитатьЗаголовки(ЧтениеЧасти);
        СтруктураСообщения = ПолучитьСтруктуруСообщения(ЗаголовкиЧасти);
        
        Если СтруктураСообщения.name = "improvementRequest" Тогда
            JSON = чтениеЧасти.ПрочитатьСимволы();
            Структура = УправлениеКонтактнойИнформациейСлужебный.СтрокуJSONВСтруктуру(JSON);
        Иначе
            Если СтруктураСообщения.name = Неопределено И СтруктураСообщения.filename = Неопределено Тогда
                Продолжить;
            КонецЕсли;  
            НовыйФайл = ТаблицаФайлов.Добавить();
            НовыйФайл.ДвоичныеДанные = ЧтениеЧасти.Прочитать().ПолучитьДвоичныеДанные();
            НовыйФайл.ИмяФайла = СтруктураСообщения.name;
            МассивПодстрок = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(СтруктураСообщения.filename, ".");
            КоличествоПодстрок = МассивПодстрок.Количество();
            НовыйФайл.Расширение = МассивПодстрок[КоличествоПодстрок-1];
        КонецЕсли;                
        
        ЧтениеЧасти.Закрыть();
        Поток.Закрыть();
        
    КонецЦикла;
        
    Возврат Новый Структура("Структура,ТаблицаФайлов", Структура, ТаблицаФайлов);
    
КонецФункции


Функция ПрочитатьЗаголовки(ЧтениеЧасти)
    
    Заголовки = Новый Соответствие();
    
    Пока Истина Цикл
        Стр = ЧтениеЧасти.ПрочитатьСтроку();
        
        Если Стр = "" Тогда
            
            Прервать;
            
        КонецЕсли;
        
        Части = СтрРазделить(Стр, ":");
        ИмяЗаголовка = СокрЛП(Части[0]);
        Значение     = СокрЛП(Части[1]);
        
        Заголовки.Вставить(ИмяЗаголовка, Значение);
        
    КонецЦикла;
    
    Возврат Заголовки;
    
КонецФункции


Функция ПолучитьСтруктуруСообщения(Заголовки)
    
    Структура = Новый Структура("name,filename");
    
    Описание = Заголовки.Получить("Content-Disposition");
    Свойства = СтрРазделить(Описание, ";", Ложь);
    Для Каждого Свойство Из Свойства Цикл
        Части = СтрРазделить(Свойство, "=", Ложь);
        ИмяСвойства = СокрЛП(Части[0]);              
        Если ИмяСвойства = "name" Тогда
            Структура.name = СтрЗаменить(СокрЛП(Части[1]), """", "");
        КонецЕсли;
        Если ИмяСвойства = "filename" Тогда
            Структура.filename = СтрЗаменить(СокрЛП(Части[1]), """", "");
        КонецЕсли;
    КонецЦикла;
    
    Возврат Структура;
    
КонецФункции