Версия для печати темы (https://pro1c.org.ua/index.php?s=4ead5185ed820d042d96a7588f7d962d&showtopic=67187)

Нажмите сюда для просмотра этой темы в обычном формате

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 _ Программирование в 1С Предприятие 7.7 _ API, передача параметров FormData в теле запроса

Автор: Makcim1981 28.02.23, 16:44

Добрый день.

1С 7.7

Стоит задача организовать обмен и получение данных через API. Проблема с передачей параметров FromData. При этом совершенно для меня непонятно почему так.
1. В первом случае передается 1 параметр и отрабатывается все нормально. (ТекстЗапроса_article_by_code_firm)
2. Во втором случаи тоже один параметр, запрос отрабатывается но пишет - "error": "Set right format [id] - put techId pro!" ... что пишет я понимаю, но как подать параметр другого типа данных не знаю. (ТекстЗапроса_order_list_get)
3. Передаю 2-ва параметра. Вообще запрос не отрабатывается, постоянно ошибка. (ТекстЗапроса_articles_firm)

Процедура test()
    URL = "https://api2.ifur.pro/api/";
    Токен = "хххххххххххххххххххххххххххххххххх";
    boundary = "7MA4YWxkTrZu0gW";  
    
    ТекстЗапроса_article_by_code_firm="--"+boundary+"
      //1 параметр
      |Content-disposition: form-data; name=""code1c""" + РазделительСтрок +
    РазделительСтрок + "
      |125" + РазделительСтрок + "
      |--" + Boundary + "--"
;      
      
    ТекстЗапроса_articles_firm="--"+boundary+"
      //1 параметр    
      |Content-disposition: form-data; name=""lang""" + РазделительСтрок +
    РазделительСтрок + "
      |ru" + РазделительСтрок + "
      |--" + Boundary + "
      //2 параметр  
      |Content-disposition: form-data; name=""zip""" + РазделительСтрок +
    РазделительСтрок + "
      |1" + РазделительСтрок + "
      |--" + Boundary + "--"
;  
      
      ТекстЗапроса_order_list_get="--"+boundary+"
      //1 параметр
      |Content-disposition: form-data; name=""id""" + РазделительСтрок +
    РазделительСтрок + "
      |64309" + РазделительСтрок + "
      |--" + Boundary + "--"
;
      
      Запрос = СоздатьОбъект("winhttp.winhttprequest.5.1");    
    Запрос.open("POST", url, 0);
    Запрос.SetRequestHeader("key", Токен);  
    Запрос.SetRequestHeader("action", "article_by_code_firm"); // ТекстЗапроса_article_by_code_firm
    //Запрос.SetRequestHeader("action", "articles_firm");  // ТекстЗапроса_articles_firm
    //Запрос.SetRequestHeader("action", "order_list_get");  // ТекстЗапроса_order_list_get
    
    Запрос.setRequestHeader("Content-Type","multipart/form-data;boundary=" + Boundary);
    Запрос.setRequestHeader("Content-Length", СтрДлина(ТекстЗапроса_article_by_code_firm));
    
    Запрос.send(ТекстЗапроса_article_by_code_firm);
    Если (Запрос.Status = 200) тогда
        Ответ = Запрос.ResponseText;  
        
        тк=СоздатьОбъект("Текст");  
        тк.ДобавитьСтроку(Ответ);        
        тк.Записать("D:\temp\answer.json");
        
    Иначе
        ТекстОшибки = "Ошибка: " + Запрос.status + " : " + Запрос.statusText;
        Сообщить(ТекстОшибки);
    КонецЕсли;
                  
КонецПроцедуры


Буду признателен если поможете. Для 7.7 либо тут уже домучать как то, либо прийдется что-то внешнее подключать. Задача примитивная, но в стандартной 7-ке с инструментами для ее решения не очень.

Спасибо.

Автор: Vofka 01.03.23, 9:08

Запросы выглядят странно. Запрос FormData должен содержать в теле строку с именами и значениями параметров. Вот пример запроса с 2 параметрами:

POST / HTTP/2.0
Host: foo.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13

say=Hi&to=Mom


У вас же, судя по коду передаются только значения.

Автор: Makcim1981 01.03.23, 10:28

Vofka @ Сегодня, 9:08 * ,

Цитата(Vofka @ 01.03.23, 9:08) *
Запросы выглядят странно. Запрос FormData должен содержать в теле строку с именами и значениями параметров.

вот такой он дикий синтаксис 1С 7.7 ... в 8-ке єто делается легко и просто, а тут геморой. Пока нашел как "правильно" передать перечитал кучу всего.

      //1 параметр
      |Content-disposition: form-data; name=""id""" + РазделительСтрок +
    РазделительСтрок + "
      |64309" + РазделительСтрок + "
      |--" + Boundary + "--"
;


id - имя; 64309 - значение

тут 2-ва варианта ... .Net использовать или Curl. Я через курл сейчас все получаю, решил не заморачиваться, но разобраться было бы интересно

Автор: Makcim1981 02.03.23, 12:10

В общем ... я решил не заморачиваться и реализовал через Curl ... тоже возникло ряд ньюансов. если кому интересно, ниже поделюсь своей реализацией:

В глобальный модуль я добавил следующее:

// ===============================  
//Пересохраняем файл ответа полученый через Curl в формат понятный 1С 7.7 (русские буквы)
Процедура глПересохранениеОтветаurn(Файл) Экспорт
    
    Байт = 255;
    СтримВход = СоздатьОбъект("ADODB.Stream");
    СтримВход.Type        = 2;
    СтримВход.charset    = "utf-8";
    СтримВход.Open();
    СтримВход.LoadFromFile(КаталогИБ() + "urn\" + Файл);
    СтримВыход = СоздатьОбъект("ADODB.Stream");
    СтримВыход.Type                = 2;
    СтримВыход.charset            = "utf-8";  
    СтримВыход.charset            = "windows-1251";
    СтримВыход.LineSeparator    = -1;
    СтримВыход.Open();
    Всего = СтримВход.size;
    Пока СтримВход.EOS = 0 Цикл
        СтримВыход.WriteText(СтримВход.ReadText(Байт), ?(Байт = -2, 1, 0));
    КонецЦикла;
    СтримВыход.SaveToFile(КаталогИБ() + "urn\" + Файл, 2);
    
КонецПроцедуры  

// ===============================    
//Добавляем задержку в секундах, что бы Curl сохранил файл и следующие операции не использовали старые или несуществующие данные
Процедура глЗадержка(КоличествоСекунд) Экспорт

    Shell = СоздатьОбъект("WScript.Shell");
    Shell.Run("ping 127.0.0.1 -n "+КоличествоСекунд, 0, 1);
    
КонецПроцедуры          

// ===============================
//Формируем строку запроса по API для выполнения в Curl
Функция глСформироватьКурлСтроку(Конт,Метод,Параметр1 = "",Параметр2 = "") Экспорт  
        
    Если Метод = "order_list_get" Тогда
        СтрокаКурл = "curl -X POST """ + СокрЛП(Конт.Фирма.АдресAPIiFurn) + """ -H ""Content-Type: multipart/form-data"" -H ""key: " + СокрЛП(Конт.Фирма.KeyAPIiFurn) + """ -H ""action: " + СокрЛП(Метод) +  """ -F ""id=" + СокрЛП(Параметр1) + """ -o " + КаталогИБ() + "urn\order.json";
    
    КонецЕсли;
              
    
    Возврат СтрокаКурл;
КонецФункции


Ну и модуле формы документа

Процедура ЗагрузитьИзurn()
    
    Если ПустоеЗначение(urni) = 1 Тогда
        Сообщить("Поле Номер замовлення в urn не заповнене !","!");
        СтатусВозврата(0);
        Возврат;
    КонецЕсли;
    
    ЗапуститьПриложение(глСформироватьКурлСтроку(Контекст,"order_list_get",СокрЛП(urni))); // Отправляем номер заказа - urni
    //если на сделать задержку на выолнение скрипта Curl (а именно его мы и запускаем),
    //то выполнение кода опередит сохранение ответа в файл, что в свою очередь приведет либо к ошибке (если файла ещё нет),
    //либо прочитаются старые данные файла
    глЗадержка(3);
    глПересохранениеОтветаiFurn("order.json");
    
    Данные = СоздатьОбъект("Текст");
    Данные.КодоваяСтраница(0);
    Данные.Открыть( КаталогИБ() + "urn\order.json");
    КолСтр  = Данные.КоличествоСтрок();
    
    Для н=1 по КолСтр Цикл
        ТекСтр = Данные.ПолучитьСтроку(н);
        //Обработка полученной строки
    КонецЦикла;
    
КонецПроцедуры



Автор: Makcim1981 02.03.23, 15:43

Цитата(Makcim1981 @ 02.03.23, 12:10) *
глПересохранениеОтветаiFurn("order.json");


Извините, тут правильное название процедуры глПересохранениеОтветаurn("order.json");

Немного поясню, что в моем примере делается:

Имеем:

Заголовки:
URL: СокрЛП(Конт.Фирма.АдресAPIiFurn)
key: Конт.Фирма.KeyAPIiFurn
action: order_list_get

FormData: параметры передаются в теле (я передаю 1, но вы по аналогии можете кидать сколько угодно, главное добавить в строке формирования)

id=Параметр1 (Пусть вас не смущает id, это название параметра у меня(у вас оно может быть любым другим))

КаталогИБ() + "urn\order.json" - Сюда сохраняю ответ, который в последствии конвертирую в понятную для 1с 7.7 кодировку.

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7
https://pro1c.org.ua