Отключить перекодировку в 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:46 )
5(1)Внешний JS в какой кодировке сохраняет файл?
>> ОтветитьВ utf ( Ltybc 12.05.2015 13:48 )
5(1)Все правильно сохраняется.
>> Ответить
Вопрос (+) ( григ 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)Поищи в инете (+) ( григ 14.05.2015 07:31 )
4(1)Где-то я видел, что к параметру в методе LoadXML добавляется строка <?xml version="1.0" encoding="utf-8" ?> или что-то в этом роде. Иначе как он узнает в какой кодировке ты ему строку даешь.
Да: lgSetAutoConvert(false); lgSetANSI(2); - надо делать не глобально, а только перед чтением/записью/использованием строки в UTF-8 в методах/свойствах ActiveX. Получил - вернул настройки, обработал,снова включил, использовал в методе, выключил и т.д.
>> ОтветитьПопробую ( Ltybc 14.05.2015 11:09 )
5(1)Но строка <?xml version="1.0" encoding="utf-8" ?> там есть, все проблемы после нее начинаются.
Но если долго возиться с рабочей станцией, все начинает работать.
Спасибо большое за библиотеку.
>> ОтветитьВот глянь ссылку:(+) ( григ 14.05.2015 13:27 )
4(1)http://tigor.com.ua/blog/2008/08/06/domdocument-loadxml-encoding-utf8-in-xml/
Вообще с UTF-8 есть мелкие тонкости по использованию.
>> Ответить
А как запустить трехзвенку на сервере? ( 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) и ищет в файлике новые запросы (по ключу). Нашел - вызвал функцию обработки в зависимости от вида запроса. Та отработала - в другой файлик сложила результат.
Так можно что угодно реализовать. В т.ч. и обратные вещи - когда макрос на серваке периодически что-то качает и складывает в файлик.
>> Ответить