Модераторы: Snowy, Poseidon, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> SwinHttp и UTF8 
:(
    Опции темы
PriZraK
Дата 4.10.2008, 05:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 22.10.2006

Репутация: нет
Всего: нет



Здравствуйте.
Delphi 2009. Пытаюсь отправить сообщение в UTF8 и принять ответ в UTF8.
Ответ успешно перевожу в String (функцией UTF8ToString) (а следовательно в Unicode, т.к. в Delphi 2009: String = UnicodeString), а с отправкой проблема, русские символы теряются в сообщении. Что необходимо исправить?

Привожу функцию общения программы-клиента с сервером.
Код

function HTTPQuery(const Query: String) : String;
  var
    HTTP        : TSwinHttp;
    DOM         : IXMLDOMDocument;
    MSGtype     : Integer;
    MSGtext     : String;
    Answer      : String;
begin
    // ответ по умолчанию
    Answer := '<System><UserID value="0"/><Session value="0"/><MSGtype value="0"/><MSGtext value=""/></System>';
    // создаём экземпляр http
    HTTP := TSwinHttp.Create(nil);
    // создаём DOM
    DOM:=CoDOMDocument.Create;
    try
      // отправляем запрос
      HTTP.InThread := false; // переводим в синхронный режим
      HTTP.Get(UTF8Encode(frmAuthorization.ServerURL + '/?userid='+IntToStr(frmAuthorization.UserID)+'&session='+frmAuthorization.Session + Query));
      if HTTP.Error = 0 then
        begin
          // ПРОВЕРКА №1
          case HTTP.Response.Code of
            404 : MessageDlg('Произошла ошибка связи — адрес сервера не доступен.',mtError,[mbOk], 0);
            403 : MessageDlg('Произошла ошибка связи — доступ к серверу запрещён.',mtError,[mbOk], 0);
            500 : MessageDlg('Ошибка в работе скриптов сервера.',mtError,[mbOk], 0);
            200 :
              begin
                // заменяем данные по умолчанию
                Answer := UTF8ToString(HTTP.Response.Body);
                // полученные данные и передаем в DOM
                DOM.loadXML(Answer);
                // ПРОВЕРКА №2. Если возникли ошибки - выводим в статусную строку
                if DOM.parseError.reason <> '' then
                  begin
                    MessageDlg('Произошла ошибка, не могу распознать ответ сервера.'+ sLineBreak +
                    'Возможные причины:' + sLineBreak +
                    ' - не верно указан путь до сервера;'+ sLineBreak +
                    ' - версия вашего клиента не совпадает с текущей;' + sLineBreak +
                    ' - ошибка в серверных скриптах;'  + sLineBreak +
                    ' - ошибка XML: ' + DOM.parseError.reason,mtError,[mbOk], 0);
                  end
                else
                  begin
                    // получаем данные
                    MSGtype := StrToInt(DOM.GetElementsByTagName('MSGtype').nextNode.attributes.item[0].nodeValue);
                    MSGtext := DOM.GetElementsByTagName('MSGtext').nextNode.attributes.item[0].nodeValue;
                    // обработка модулем I (вывод сообщений пользователю)
                    if (MSGtype >= 1) and (5 >= MSGtype) then
                    begin
                      // заменяем [BR] на перенос строки
                      MSGtext := BrToLineBreak(MSGtext);
                      // исходя из типа сообщения - выводим диалог
                      Case MSGtype of
                        1 : MessageDlg(MSGtext,mtInformation,[mbOk], 0);
                        2 : MessageDlg(MSGtext,mtWarning,[mbOk], 0);
                        3 : MessageDlg(MSGtext,mtConfirmation,[mbOk], 0);
                        4 : MessageDlg(MSGtext,mtError,[mbOk], 0);
                        5 : MessageDlg(MSGtext,mtCustom,[mbOk], 0);
                      end;
                  end;
              end;
              //InputBox('Запрос', 'URL:', Query);
              //InputBox('Ответ', 'Ответ:', Answer);
              //MessageDlg(IntToStr(HTTP.ResponseCode),mtError,[mbOk], 0);
            end;
          else
            MessageDlg('Произошла HTTP ошибка. Код: '+IntToStr(HTTP.Response.Code),mtError,[mbOk], 0);
          end;
        end
      else
        begin
          MessageDlg('При попытке подключиться к серверу произошла ошибка.',mtError,[mbOk], 0);
        end;
    finally
      HTTP.Free;
      DOM     :=nil;
      Result  :=Answer;
    end;
end;

PM MAIL ICQ Skype GTalk   Вверх
MetalFan
Дата 4.10.2008, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 14
Всего: 128



а есть ли необходимость перевода в UnicodeString из UTF8 перед загрузкой в IXMLDOMDocument?

з.ы. может SwinHTTP не адаптирован для работы в 2009й делфе?

Это сообщение отредактировал(а) MetalFan - 4.10.2008, 20:01


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
PriZraK
Дата 5.10.2008, 07:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 22.10.2006

Репутация: нет
Всего: нет



Цитата

а есть ли необходимость перевода в UnicodeString из UTF8 перед загрузкой в IXMLDOMDocument?

Да, есть, иначе кириллица представляет собой «краказяблы»  smile 
Цитата

з.ы. может SwinHTTP не адаптирован для работы в 2009й делфе?

В том то и дело, имхо, после передачи url строки в SwinHTTP, он преобразуется её обратно в String, а следовательно в таком виде (Unicode) она передаётся на сервер. Мои исправления кода SwinHTTP не увенчались успехом. Может быть обратится напрямую к разработчику? 

Делал на idHTTP — работает, но, черт, как медленно!

Delphi 2009 понравился, уже не хочется возвращаться к 2007, возможно уже есть иной компонент для работы с HTTP/HTTPS работающий так же быстро (или быстрее) как SwinHTTP?
PM MAIL ICQ Skype GTalk   Вверх
MetalFan
Дата 5.10.2008, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 14
Всего: 128



используй напрямую функции WinInet.

Добавлено через 32 секунды
з.ы. странно, что за версия индей у тебя? у меня проблем с Indy не наблюдается...


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
PriZraK
Дата 9.10.2008, 10:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 22.10.2006

Репутация: нет
Всего: нет



Посмотрел что же приходит на сервер.
Код

@$fp = fopen("test.txt", "a", 1);
fwrite($fp, $_SERVER["QUERY_STRING"]);
flock($fp, 3);
fclose($fp);

Оказалось, что русский текст отлично доходит до сервера, но а в БД не сохраняется, то есть при выполнении кода, подобного приведённому ниже, получаем пустую строку в БД.
Код

@$link = mysql_connect($dbhost, $dbuser, $dbpass) or die ("Нет соединения с базой данных.");
@mysql_select_db($dbname,$link) or die("База данных не была найдена на сервере.");
@mysql_query("set names 'utf8'");
@mysql_query("set character_set_database='utf8'");
@mysql_query("set character_set_server='utf8'");
mysql_query("UPDATE equipment SET comment='".$comment."' WHERE id='".$id."'") or die("Ответ базы данных: не могу обновить информацию");

От безысходности добавил перекодировку из windows-1251 в UTF-8.
Код

$comment = iconv('windows-1251','UTF-8',$comment);

И, о чудо, текст сохранился! Но такой бред оставлять не хочется.

А по поводу: 
Цитата
используй напрямую функции WinInet
 почитал статью, но лишь больше запутался, новичок я в этом :(

Это сообщение отредактировал(а) PriZraK - 9.10.2008, 10:53
PM MAIL ICQ Skype GTalk   Вверх
Snowy
Дата 9.10.2008, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Проверь что уходит от клиента (маппером или сниффером).
Если уходит всё нормально, то вопрос уже не к Delphi.
Если не корректно - будем смотреть...
PM MAIL   Вверх
PriZraK
Дата 9.10.2008, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 22.10.2006

Репутация: нет
Всего: нет



В качестве сниффера выбрал "Ethereal" версии 0.99.0, вот что он поймал. Это URL-запрос на сохранение информации об оборудовании. 
Код

GET /XMLexplorer/?userid=1&session=7b3ebfb7fb6364e&action=EquipmentEditSave&id=560&parent=1&model=3&router=2&router_vlan=&vlan_mode=3&map_main=2764&map_addrn=7229&ups=0&ipaddress=10.66.92.118&mask=255.255.255.252&gateway=10.66.92.117&cpu_vlan=&comment=.... HTTP/1.1

User-Agent: User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)

Host: [адрес_хоста]

Cache-Control: no-cache

Интересует переменная "comment", в моём случае вернувшая несколько точек, за место русского текста, возможно проблема в кодировке, по этому привожу весь пакет. Хост заменён.
Код

0000   00 1c f0 1d 74 c2 00 30 4f 53 de f0 08 00 45 00  ....t..0OS....E.
0010   01 d4 12 41 00 00 80 2f 10 4f 0a 00 02 52 0a 18  ...A.../.O...R..
0020   00 02 30 81 88 0b 01 b0 f5 02 00 a3 bb 09 00 92  ..0.............
0030   91 31 21 45 00 01 af 12 40 40 00 80 06 25 72 5d  .1!E....@@...%r]
0040   5f ae 03 d5 8d e0 a6 11 f8 00 50 9e 17 d4 6e e3  _.........P...n.
0050   a7 20 94 50 18 fb 88 0b 23 00 00 47 45 54 20 2f  . .P....#..GET /
0060   58 4d 4c 65 78 70 6c 6f 72 65 72 2f 3f 75 73 65  XMLexplorer/?use
0070   72 69 64 3d 31 26 73 65 73 73 69 6f 6e 3d 37 62  rid=1&session=7b
0080   33 65 62 66 62 37 66 62 36 33 36 34 65 26 61 63  3ebfb7fb6364e&ac
0090   74 69 6f 6e 3d 45 71 75 69 70 6d 65 6e 74 45 64  tion=EquipmentEd
00a0   69 74 53 61 76 65 26 69 64 3d 35 36 30 26 70 61  itSave&id=560&pa
00b0   72 65 6e 74 3d 31 26 6d 6f 64 65 6c 3d 33 26 72  rent=1&model=3&r
00c0   6f 75 74 65 72 3d 32 26 72 6f 75 74 65 72 5f 76  outer=2&router_v
00d0   6c 61 6e 3d 26 76 6c 61 6e 5f 6d 6f 64 65 3d 33  lan=&vlan_mode=3
00e0   26 6d 61 70 5f 6d 61 69 6e 3d 32 37 36 34 26 6d  &map_main=2764&m
00f0   61 70 5f 61 64 64 72 6e 3d 37 32 32 39 26 75 70  ap_addrn=7229&up
0100   73 3d 30 26 69 70 61 64 64 72 65 73 73 3d 31 30  s=0&ipaddress=10
0110   2e 36 36 2e 39 32 2e 31 31 38 26 6d 61 73 6b 3d  .66.92.118&mask=
0120   32 35 35 2e 32 35 35 2e 32 35 35 2e 32 35 32 26  255.255.255.252&
0130   67 61 74 65 77 61 79 3d 31 30 2e 36 36 2e 39 32  gateway=10.66.92
0140   2e 31 31 37 26 63 70 75 5f 76 6c 61 6e 3d 26 63  .117&cpu_vlan=&c
0150   6f 6d 6d 65 6e 74 3d f2 e5 f1 f2 20 48 54 54 50  omment=.... HTTP
0160   2f 31 2e 31 0d 0a 55 73 65 72 2d 41 67 65 6e 74  /1.1..User-Agent
0170   3a 20 55 73 65 72 2d 41 67 65 6e 74 3a 20 4d 6f  : User-Agent: Mo
0180   7a 69 6c 6c 61 2f 34 2e 30 20 28 63 6f 6d 70 61  zilla/4.0 (compa
0190   74 69 62 6c 65 3b 20 4d 53 49 45 20 36 2e 30 3b  tible; MSIE 6.0;
01a0   20 57 69 6e 64 6f 77 73 20 4e 54 20 35 2e 31 29   Windows NT 5.1)
01b0   0d 0a 48 6f 73 74 3a 20 6e 6d 2e 65 2d 74 61 67  ..Host:         
01c0   69 6c 2e 72 75 0d 0a 43 61 63 68 65 2d 43 6f 6e  il.ru..Cache-Con
01d0   74 72 6f 6c 3a 20 6e 6f 2d 63 61 63 68 65 0d 0a  trol: no-cache..
01e0   0d 0a                                            ..

Может быть необходима иная информация? — подскажите название сниффера, для решения этого вопроса.
PM MAIL ICQ Skype GTalk   Вверх
Snowy
Дата 9.10.2008, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Это не точки. Это "тест " в кодировке 1251.
А переконвертация в 1251 происходит, скорее всего автоматически в момент передачи параметра-строки.
2009 с собой нет - нужно посмотреть, как она относится к utf-8
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0696 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.