Отключить перекодировку в XMLHTTP

0 (0)
  • Развернуть Отключить перекодировку в XMLHTTP ( Ltybc  06.05.2015 15:47 )
    5(1)
    Возникла проблема с тем, что объект XMLHTTP, при вызове через rslx все кодировки переводит к досовской.

    Существует в Москве такой сервис как РНИП, позволяющий платить в любую контору, ассоциированную с мэрией.
    Для этого он рассылает через веб-сервис каталог получателей в xml, в котором есть полные атрибуты получателей.
    Но, к сожалению, в этих атрибутах используется все богатство русского языка в разрезе utf-8. И двойные кавычки уголком « и невнятные апострофы и только что не псевдографика.
    Все это при перекодировке в cp866 микрософт легко заменяет знаком <
    Чем тут же разрушает структуру xml.

    И вот вопрос, можно ли как-нибудь перекодировку отключить? Потому что на голом JS скрипт
     var req = new ActiveXObject("Msxml2.XMLHTTP");
     req.open("POST", server_url, false);
     req.send(xml);
     alert(req.responseText);
    
    возвращает чистые данные в utf-8. А из-под RSL тоже самое не работает - идет битый xml c кодировкой 866 .

    >> Ответить
    • Развернуть Задавался обратным вопросом несколько лет назад. Решения не нашёл. ( tema  11.05.2015 13:57 )
      5(1)
      https://isupport.softlab.ru/Forum/ZoneForum/topic.asp?Forum=7&ID=53713&CurM=53714
      айс 220503, 233922
      >> Ответить
    • Развернуть Где можно xml-файлик взять - посмотреть? (+) ( григ  12.05.2015 07:39 )
      5(1)
      Нужно разобраться на каком этапе косяк. Сам ActiveX-объект корежит (что вряд ли) или это делает его клиент в РСЛ-е.
      Если на голом JS скрипт возвращает верные данные, то скорее всего переконвертация идет в длм-ке РСЛ-я. В старинном макросе по rslx.d32 нашел:
      /* Задаем режим автоматического конвертирования строк из OEM в ANSI и
      обратно. Режим конфертирования включается если IsGUI == false */
      SetClientMode (IsGUI);
      И потом конвертация ToOEM и ToANSI вроде как взаимно обратные без разрушения строки.
      >> Ответить
      • Развернуть не получилось :( ( tema  12.05.2015 10:06 )
        5(1)
        <?xml version="1.0" encoding="WINDOWS-1251"?>
        <root>
        <name>ООО «ПУПКИНС»</name>
        </root>
        

        import rslx, rsexts;
        
        const strFilePath="myxml.xml";
        
        var DOMDoc = ActiveX("MSXML.DOMDocument");
        DOMDoc.async = False;
        
        if (GetFileInfo(strFilePath))
            DOMDoc.Load(strFilePath);
            printLn(DOMDoc.documentElement.selectSingleNode("name").text);
            SetClientMode (true);
            printLn(DOMDoc.documentElement.selectSingleNode("name").text);
            SetClientMode (false);
            printLn(DOMDoc.documentElement.selectSingleNode("name").text);
        else
            printLN(strFilePath + " not found");
        end;
        

        всегда возвращает в OEM с перекодировкой из « в <

        >> Ответить
        • Развернуть Я не смог победить ( Ltybc  12.05.2015 10:24 )
          4(1)
          XMLHTTP всеми своими методами response* возвращает досовскую кодировку, как его не упрашивай.
          Пока что внешним JS скачиваю файл на диск, а потом читаю его с диска через DOMDocument.loadXML.
          >> Ответить
        • Развернуть Вопрос (+) ( григ  12.05.2015 13:45 )
          5(1)
          В примере файла encoding="WINDOWS-1251", а реально кодировка самого файла UTF-8 (сужу по виду двойных кавычек)
          Может надо encoding="UTF-8"?
          >> Ответить
          • Развернуть За него не скажу, а у меня все правильно. ( Ltybc  12.05.2015 13:50 )
            5(1)
            XMLHTTP отдает документ, у которого прописано <?xml version="1.0" encoding="UTF-8"?>,
            а внутри - cp866.
            Я пробовал с этими кодировками даже играться - без толку.

            >> Ответить
          • Развернуть не понял вопроса. можно сделать файл и в UTF-8 разницы никакой ( tema  12.05.2015 14:08 )
            5(1)
            суть в том, что объекты ActiveX XMLHTTP, MSXML и т.п. хранят данные в юникоде и текстовые методы и свойства у них юникодные. RS же конвертирует строки OEM<->UNICODE при взаимодействии с объектами ActiveX, и не известен метод заставить его не делать этого, а отдать/получить строку в сыром, юникодном виде.
            >> Ответить
            • Развернуть Понял проблему, понял (-) ( григ  12.05.2015 14:36 )
              5(1)
              Not specified
              >> Ответить
            • Развернуть Сам РСЛ не поддерживает Юникод (+) ( григ  12.05.2015 14:48 )
              5(1)
              Как ему передать строку в Юникоде? Любой 0 - это для него конец строки. Передавать 16-ю строку? Как ты ее дальше будешь юзать?
              >> Ответить
              • Развернуть Угу, UTF-8 не содержит ноликов, поэтому его можно юзать как обычную строку (+) ( григ  12.05.2015 15:25 )
                4(1)
                Т.е. полученную строку WideChar не преобразовывать в MultiByte, а сразу рассматривать как MultiByte.
                В принципе в 3-х звенке для длм-ок lgx.d32,lgxs.d32 можно ввести еще один глобальный флаг: IsNotConvWC_MB
                Если он в true, то для строковых параметров не делать конвертацию WC <-> MB. Это не касается имен свойств и методов - там всегда должна быть конвертация.
                Что думаете?
                >> Ответить
                • Развернуть Меня пугает ваш разговор с самим собой ))), но попробовать можно ( Ltybc  12.05.2015 15:54 )
                  5(1)
                  Единственная проблема - нам, например, всё это необходимо именно в двухзвенке.
                  Потому что проще с сервера работать, чем с пользователями, у которых еще и доступа к серверам СМЭВ нет.
                  Но трехзвенка, так трехзвенка, лишь бы работало.
                  >> Ответить
                  • Развернуть Я длм-ку lgx.d32 лет 15 назад писал (+) ( григ  13.05.2015 12:51 )
                    5(1)
                    Поэтому пытаюсь вспомнить и с вами обсудить :)
                    Сделал изменения - послал на e-mail. Пробуйте.

                    Когда ActiveX читает xml, то переводит его в Unicode. И при чтении свойства клиент ActiveX уже не знает исходной кодировки. Можно только сказать в какую кодировку Unicode проконвертировать. Сделал в функции lgSetANSI(reg) изменения: reg может быть:
                    0 или false - кодировка OEM
                    1 или true - кодировка ANSI
                    2 - кодировка UTF-8
                    последняя действует только для значений свойств, параметров и т.д. и не действует для имен свойств и методов.

                    Запустить 3-х звенку на сервере - вообще не проблема. У нас много задач так крутится.

                    >> Ответить
                    • Развернуть Не вышло. Или я не понял задумку ( Ltybc  13.05.2015 16:17 )
                      5(1)
                      В таком варианте все вылетает как и было
                      	xmlDoc 		= TLGActiveX("MSXML2.DOMDocument");
                      	xmlDocRes 	= TLGActiveX("MSXML2.DOMDocument");
                      	req 		= TLGActiveX("Msxml2.XMLHTTP.6.0");
                      
                      	lgSetAutoConvert(true); lgSetANSI(1);
                      
                      	xmlDoc.loadXML(xml);
                      
                      	req.Open("POST", server_url, false);
                      	req.Send(xmlDoc.xml);
                      
                      	while ((req.readyState != 4) 
                      			AND (TestEvent(10) != 27)
                      		)
                      		Message("Идет запрос...");
                      	end;
                      
                      	xmlDocRes.async = false;
                      
                      	xmlDocRes.LoadXML(req.responseText);
                      
                      Если поставить
                      lgSetAutoConvert(true); lgSetANSI(2);
                      
                      то все работает без ошибок, но кириллица приводится в страшный вид казР_Р°С╪РчР№С_С'Р_Р° РїР_ Р_Р_С_Р_Р_С_ Р_Р_С_РєР_Рч (Р_Р_С_РєР_Р_Р°С_С:РёС'РчРєС'С_С_Р°


                      >> Ответить
                      • Развернуть Поправка. ( Ltybc  13.05.2015 16:25 )
                        5(1)
                        Вот так работает получение
                        lgSetAutoConvert(true); lgSetANSI(2);
                        
                        XMLHTTP отдает правильную строку в utf-8.
                        Но DomDocument на последней строке не может ее загрузить и остается пустым по непонятным причинам.
                        >> Ответить
                        • Развернуть Точнее вот так ( Ltybc  13.05.2015 16:26 )
                          5(1)
                           lgSetAutoConvert(false); lgSetANSI(2);
                          

                          >> Ответить
                          • Развернуть Поищи в инете (+) ( григ  14.05.2015 07:31 )
                            4(1)
                            Где-то я видел, что к параметру в методе LoadXML добавляется строка <?xml version="1.0" encoding="utf-8" ?> или что-то в этом роде. Иначе как он узнает в какой кодировке ты ему строку даешь.
                            Да: lgSetAutoConvert(false); lgSetANSI(2); - надо делать не глобально, а только перед чтением/записью/использованием строки в UTF-8 в методах/свойствах ActiveX. Получил - вернул настройки, обработал,снова включил, использовал в методе, выключил и т.д.

                            >> Ответить
                    • Развернуть А как запустить трехзвенку на сервере? ( Ltybc  13.05.2015 17:34 )
                      5(1)
                      Я не очень понял.
                      Вот у нас пользователь нажимает кнопку, как сделать, что TLGActivex отработал на стороне сервера, а не не рабочей станции?
                      >> Ответить
                      • Развернуть У нас каталог терминала находится на сервере и (+) ( григ  14.05.2015 07:21 )
                        5(1)
                        запускают его админы через RAdmin или он запускается как отдельная задача по расписанию.
                        Пользователи туда доступ не имеют. Если нужно пользователя включить - то делается через базу запросов-ответов, в каждой задаче по своему.

                        >> Ответить
                        • Развернуть Слишком сложно выходит ( Ltybc  14.05.2015 11:08 )
                          4(1)
                          Нам бы по кнопке сразу получать данные запроса. Ладно, посмотрим, может и трехзвенку нормально на всех станциях наладим.
                          >> Ответить
                          • Развернуть Да чего там сложного (+) ( григ  14.05.2015 13:20 )
                            4(1)
                            Пользователь кнопку нажал - в файлик добавилась запись-запрос. Далее макрос в цикле ищет в файлике ответов запись с AutoZ запроса. Макрос на серваке висит в бесконечном цикле с dcSleep(1500) и ищет в файлике новые запросы (по ключу). Нашел - вызвал функцию обработки в зависимости от вида запроса. Та отработала - в другой файлик сложила результат.
                            Так можно что угодно реализовать. В т.ч. и обратные вещи - когда макрос на серваке периодически что-то качает и складывает в файлик.

                            >> Ответить