Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Кодировка ответа в 1С по запросу API
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 > Программисту > Программирование в 1С Предприятие 7.7
Makcim1981
Добрый день. Есть задача соединить 1С 7.7 и сайт посредством API. Ранее API в 1С никогда не использовал. Воспользовался гуглом, нашел, как ни странно, не много информации, но все же. Накидал в 1С небольшую процедурку:

Процедура Сформировать()    

    ИмяФайлаBody = "d:\Temp\test.json";
    
    ТочкаВхода="https://api.ifurni.net/api/";

    oADOStream = СоздатьОбъект("ADODB.Stream");
    oADOStream.Type = 1; //Binary
    oADOStream.Open();
    oADOStream.LoadFromFile(ИмяФайлаBody);

    WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");

    //Отключаем проверку сертификата
    Скрипт= СоздатьОбъект("MSScriptControl.ScriptControl");
    Скрипт.language="javascript";
    Скрипт.AddObject("WinHttp",WinHttp);
    Скрипт.Eval("WinHttp.Option(4)=13056");//intSslErrorIgnoreFlags
    Скрипт.Eval("WinHttp.Option(6)=true");//blnEnableRedirects
    Скрипт.Eval("WinHttp.Option(12)=true");//blnEnableHttpsToHttpRedirects
    //Сам запрос
    WinHttp.Open("POST", ТочкаВхода, 0);
    //WinHttp.setRequestHeader("Accept", "text/json");
    WinHttp.setRequestHeader("Content-type", "text/json");    
    WinHttp.SetRequestHeader("Content-length", "" + oADOStream.Size);     
    WinHttp.SetRequestHeader("key", "MasterKey");  
    WinHttp.SetRequestHeader("action", "get_worker_list");    
    
    Попытка
        WinHttp.Send(oADOStream);
                
        СтрокаОтветаНаЗапрос = WinHttp.ResponseText();  

       тк=СоздатьОбъект("Текст");
        тк.ДобавитьСтроку(СтрокаОтветаНаЗапрос);
        тк.Записать("D:\temp\test_return.json");

        Статус = СокрЛП(WinHttp.Status);
        Описание = СокрЛП(WinHttp.StatusText);    
        Сообщить(СтрокаОтветаНаЗапрос);  
    Исключение
        Сообщить("Ошибка: "+ОписаниеОшибки(),"!");
    КонецПопытки;
КонецПроцедуры


Тело запроса грузится из переменной - ИмяФайлаBody. Ответ получаем в строке Сообщения (если ответ не будет слишком велик и не выдаст ошибку, это не проблема) ну и записывваем в файл test_return.json.

Все полностью отрабатывается и получаем ответ:

{"status":"ok","error":"","data":{"client_1":{"phone":"+38 (097) 875-26-44","name":"???»N?N???N? 1","ifp_id":"125","code":null}}}


И Вот сам вопрос ... как мне получить Кирилические символы в нормальном виде. (в данном примере вот они - "name":"???»N?N???N? 1")

Пробовал добавлять в заголовки:

WinHttp.SetRequestHeader("Accept-Language", "ru");
WinHttp.SetRequestHeader("Accept-Charset", "utf-8");
WinHttp.SetRequestHeader("Content-Language", "ru");
WinHttp.SetRequestHeader("Content-Charset", "utf-8");


Также перед отправкой метода POST:

WinHttp.Option(2,"utf-8");


Результат один и тот же.

Ещё хотел поинтересоватся, кто уже работал с API. Есть какие то готовые парсеры для строки или каждый API по разному разбирается, нет каких то статичных якорей и т.д. В общем посоветуйте как лучше разбирать

Спасибо.
Vofka
Цитата(Makcim1981 @ 21.06.22, 11:38) необходимо зарегистрироваться для просмотра ссылки
Есть какие то готовые парсеры для строки

Современные инструменты умеют превращать json в то, с чем можно работать. 1С 7.7 штатно вряд-ли. Но необходимо зарегистрироваться для просмотра ссылки первая ссылка в Гугле, может то, что вам надо.

Цитата(Makcim1981 @ 21.06.22, 11:38) необходимо зарегистрироваться для просмотра ссылки
как мне получить Кирилические символы в нормальном виде

А так?
WinHttp.SetRequestHeader("Accept-Charset", "windows-1251");
WinHttp.SetRequestHeader("Content-Charset", "windows-1251");


WinHttp.Option(2,"windows-1251");
Makcim1981
Vofka @ Сегодня, 14:48 необходимо зарегистрироваться для просмотра ссылки ,
Цитата
А так?
WinHttp.SetRequestHeader("Accept-Charset", "windows-1251");
WinHttp.SetRequestHeader("Content-Charset", "windows-1251");


WinHttp.Option(2,"windows-1251");


ответ тот же ... поражает то, что не важно, что я ставлю windows-1251 или utf-8 ответ один и тот же, прокозябры ("???»N?N???N? 1") не меняются

при этом разработчик пишет, что кодировка utf-8
Vofka
А тут нигде нету возможности указать кодировку?
тк=СоздатьОбъект("Текст");
тк.ДобавитьСтроку(СтрокаОтветаНаЗапрос);
тк.Записать("D:\temp\test_return.json");

Могу предположить, что либо при создании объекта можно указать кодировку, либо при записи. Если можно, укажите utf-8.
Makcim1981
Vofka @ Сегодня, 15:43 необходимо зарегистрироваться для просмотра ссылки ,

Указать кодировку для Объекта типа текст можно (ну и только, что попробовал на всякий случай), по Монитору четко видно, что сама функция WinHttp.ResponseText() возвращает уже в кракозябрах. Я так понимаю как то надо указать напрямую до запроса, но не могу понять как
Vofka
А что-то из этого не работает?

WinHttp.setRequestHeader("Content-type", "text/json;Charset=ISO-8859-1");


WinHttp.setRequestHeader("Content-type", "text/json;Charset=UTF-8");


WinHttp.setRequestHeader("Content-type", "text/json;Charset=Windows-1251");


Цитата(Makcim1981 @ 21.06.22, 21:17) необходимо зарегистрироваться для просмотра ссылки
по Монитору четко видно

Что за Монитор?
Makcim1981
Цитата(Vofka @ 22.06.22, 9:59) необходимо зарегистрироваться для просмотра ссылки
что-то из этого не работает?

WinHttp.setRequestHeader("Content-type", "text/json;Charset=ISO-8859-1");


WinHttp.setRequestHeader("Content-type", "text/json;Charset=UTF-8");


WinHttp.setRequestHeader("Content-type", "text/json;Charset=Windows-1251");


Тоже ничего не меняет. Меня смущает само представление в котором я получаю ответ "name":"???»N?N???N? 1" (там должно быть "name": "Клієнт 1"), представление какое то, как будто уже, что то перекодировываться пыталось.

Цитата(Vofka @ 22.06.22, 9:59) необходимо зарегистрироваться для просмотра ссылки
Что за Монитор?


ну в отладчике я имел ввиду ... при отладке кода глянул
popenko
Makcim1981 @ Сегодня, 10:14

допишите

    ИмяФайла = ("D:\temp\test_return.json");  
    
    Если ФС.СуществуетФайл(ИмяФайла)=1 Тогда
        
        
        Текст = СоздатьОбъект("Текст");
        Текст.КодоваяСтраница(0); // Win  
        Текст.Открыть(СокрЛ(ИмяФайла));
        
        Если Текст.КоличествоСтрок()=0 Тогда
            Предупреждение("В файле нет данных");
        Иначе  
            
            НомерСтр = 1;
            Пока НомерСтр<=Текст.КоличествоСтрок() Цикл
                Состояние("Обрабатываю строку № "+НомерСтр);  
                ТекущаяСтрока = СокрЛП(Текст.ПолучитьСтроку(НомерСтр));  
                Если ПустаяСтрока(ТекущаяСтрока) =1 Тогда
                    НомерСтр = НомерСтр + 1;  
                    Продолжить;
                КонецЕсли;                  
                
                НомерСтр = НомерСтр + 1;  
            КонецЦикла;
            
            сообщить(ТекущаяСтрока);    
            сообщить(_ПреобразоватьСтрокуИзУТФ8(ТекущаяСтрока));    
            
        КонецЕсли;        
    КонецЕсли;



а перед своей процедурой


Makcim1981 @ Сегодня, 10:14 необходимо зарегистрироваться для просмотра ссылки ,


// Преобразовать строку из UTF-8
Функция _ПреобразоватьСтрокуИзУТФ8(Стр)
    Длина=СтрДлина(Стр);
    Итог="";
    Для Н=1 По Длина Цикл
        Знак=Сред(Стр,Н,1);
        Код=КодСимв(Знак);
        Если Код<128 Тогда
            Итог=Итог+Знак;
        ИначеЕсли (Код>=128)И(Код<192) Тогда
        Иначе
            Н=Н+1;
            Знак2=Сред(Стр,Н,1);
            Код2=КодСимв(Знак2);
            Если Код=208 Тогда
                Если Код2=129 Тогда Итог=Итог+"Ё";
                Иначе Итог=Итог+Симв(КодСимв("А")+Код2-144);
                КонецЕсли;
            ИначеЕсли Код=209 Тогда
                Если Код2=145 Тогда Итог=Итог+"ё";
                Иначе Итог=Итог+Симв(КодСимв("р")+Код2-128);
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    Возврат Итог;
КонецФункции
Makcim1981
popenko @ Сегодня, 11:52 необходимо зарегистрироваться для просмотра ссылки ,
Не помогло ... мне кажется, что проблема в самом объекте WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1") ... точнее в правильной передаче параметров в него.

уже на этом этапе возвращается СтрокаОтветаНаЗапрос = WinHttp.ResponseText(); строка с краказябрами которые нельзя конвертировать. То есть мне кажется, что в самом объекте уже перекодируется на нечитаемую фигню.

После примененного выше совета разница не велика )

{"status":"ok","error":"","data":{"client_1":{"phone":"+38 (097) 875-26-44","name":"???»N?N???N? 1","ifp_id":"125","code":null}}} - до
{"status":"ok","error":"","data":{"client_1":{"phone":"+38 (097) 875-26-44","name":"???N?N???N? 1","ifp_id":"125","code":null}}} - после

Просто убрало один символ функцией


Прийдется либо curl либо другой объект пробовать (((
Makcim1981

попробовал по другому


    httpRequest = СоздатьОбъект("MSXML2.xmlhttp");
    httpRequest.open("POST", "https://api.ifur.net/api",0);
    httpRequest.setRequestHeader("Content-Type", "text/xml");
    httpRequest.setRequestHeader("key", "MasterKey");
    httpRequest.setRequestHeader("action", "client_get");
      
    httpRequest.send();
    
    ОтветСервера = httpRequest.responseText;



так отработало нормально. нет проблем с кодировками
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.