Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Delphi: Сетевое программирование > Пример http клиент-сервера с поддержкой кирилицы


Автор: dreyqq 13.12.18, 07:57
Пришел момент перевода своего приложения с локального на клиент-сервер
В чём нужна подсказка:
Нужно на http обмениваться инфой между клиентом и сервером, желательно с использованием XML, так как его проще обрабатывать и через него я могу передать то количество параметров что мне нужно. Всё ничего, но возникла проблема с кирилицей... Ответ сервера в кирилице я нашел как сделать:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    procedure TForm1.hts1CommandGet(AContext: TIdContext;
      ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
    begin
      AResponseInfo.ContentType := 'text/html; charset=windows-1251'; // для русских ответов
      ...
    end;

и сервер клиенту отвечает правильно, но принять кирилицу не выходит...

1) Как правильно отправить с помощью POST кирилицу, чтобы сервер её принял?
2) Там ли я на сервере пытаюсь обработать POST запрос?


delphi RAD Studio 10.2
IDHTTP - клиент
IDHTTPServer - сервер

Автор: Mr.Delphist 13.12.18, 20:58
Самое главное: не надо собирать XML вручную - только через TXMLDocument или его аналог.

Например, так неправильно:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    var xml: string;
    xml = '<?xml version="1.0" encoding="windows-1251"?>' // руками указали processing instruction
        + '<tag-content>Тут русский текст</tag-content>'; // руками напихали контент, безотносительно processing instruction


Дело в том, что XML - это не текст. Это байтовый поток, который для большинства случаев выглядит как текст. Но чуть шаг в сторону - надо руками энкодить в правильный байтовый формат или же использовать готовые энкодеры, как TXMLDocument (который, в свою очередь, лишь обёртка вокруг системного компонента MS XML).

Вот ещё на эту тему:
http://okitgo.ru/xml/kodirovka-xml.html

Автор: Fr0sT 14.12.18, 07:46
Для начала я бы порекомендовал применять utf8, национальные кодировки отмирают.
Во-вторых, content-type в заголовке http ответа и кодировка xml - это две абсолютно разные и совершенно независимые штуки. Более того, значение атрибута encoding документа xml не означает, что сам документ в этой кодировке. Поэтому сниффер в руки и смотреть, что отправляется и получается

Автор: Mr.Delphist 14.12.18, 09:19
Цитата Fr0sT @
Более того, значение атрибута encoding документа xml не означает, что сам документ в этой кодировке.

Вот как раз это бывает, если собирать контент руками. Тогда парсеры XML спотыкаются.

Автор: dreyqq 14.12.18, 18:55
Отправляю
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    var
    zap:tstringlist;
    ...
    begin  
    zap.Add('p1=параметр');
    IDHTTP1.Post(adr, zap);
    ...

смотрю HTTP analizer V7
Там видно P1 и значение параметр

Принимаю
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    procedure TForm1.IDHTTPserverCommandGet(AContext: TIdContext;
      ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
    begin
    ARequestInfo.ContentEncoding:='text/html; charset=windows-1251'; // это чтобы на руссок отвечало. Работает
    memo1.Text:=ARequestInfo.Params.Text;


... и полученый текст в мемо... p1=параметÑ
Как ЭТО победить?

Автор: dreyqq 14.12.18, 21:11
С отправкой на сервер проблему решил, сервер теперь принимает русские символы
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    IDHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
    IDHTTP.Request.Charset := 'utf-8';
    ... далее отправляю запрос


но появилась проблема в ответе. Если ранее я ставил в настройках сервера
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    AResponseInfo.ContentType := 'text/html; charset=windows-1251'; // для русских ответов

и клиент нормально принимал русский, то сейчас сервер принимает всё нормально, а вот клиент принимает ????? вместо
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    AResponseInfo.ContentText :='ответ';

Как это решить?

Автор: dreyqq 15.12.18, 08:43
Победил
Кому нужно через IDHTTP отправлять запрос и принимать его с помощью IDHTTPserver и при этом использовать русский
IDHTTP перед отправкой запроса
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    IDHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
    IDHTTP.Request.Charset := 'utf-8';
    ...


IDHTTPserver перед отправкой ответа
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    AResponseInfo.ContentType:='application/x-www-form-urlencoded';
    AResponseInfo.CharSet:='utf-8';
    ...


Только так нормально отправляет русский запрос и ответ

Автор: Fr0sT 17.12.18, 07:25
Молодец! Продираясь через тернии, самостоятельно открыл то, что я давно посоветовал в #3. Что ж, личный опыт всегда лучше усваивается, чем советы

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)