Конференция "Сети" » HTTPEncode для WideString ? [D7, WinXP]
 
  • Mutilator (20.02.12 21:38) [0]
    не пойму каким образом корректно конвертировать WideString строку (Mädarõigas) для правильной отправки POST запросом по HTTP. Браузер конвертирует ее в

    M%E4dar%F5igas

    Используя стандартную библиотеку HTTPApp и ее функцию HTTPEncode теряем WideString и на выходе получаем Madaroigas.
    Если приводить перед конвертацией строку к UTF8

    HTTPEncode(UTF8Encode('Mädarõigas'))

    получаем

    M%C3%A4dar%C3%B5igas, что явно не соответствует преобразованию в браузере.

    Бьюсь над этим вопросом вторые сутки помогите кодом.
  • sniknik © (20.02.12 21:52) [1]
    надо на D2009 и больше переходить... там HTTPEncode с юникодом должна быть. ... наверное.
  • Mutilator (20.02.12 21:54) [2]
    Такое решение очевидно, но не подходит.
  • sniknik © (20.02.12 22:05) [3]
    > M%C3%A4dar%C3%B5igas, что явно не соответствует преобразованию в браузере.
    главное чтобы в "обратку" разворачивалось, а не соответствие в браузере.

    кстати браузер может только показывает так, а на деле даже не кодирует...
    > M%E4dar%F5igas
    вот не похоже на юникод... однобайтный
    %E4 - 228 - ф
    %F5 - 245 - ї
  • sniknik © (20.02.12 22:11) [4]
    если только раскодировать с учетом, что это точно юникод... и первый байт добавлять. х.з. как оно там делает. если так то вполне можно свою функцию "asбраузер" написать...
  • Mutilator (21.02.12 00:05) [5]
    M%E4dar%F5igas получено сниффером непосредственно с HTTP. тут ошибки точно нет. Причем все браузеры кодируют именно так. Просто не понятно почему такие важные и казалось бы простые вещи так трудно реализовать в делфи (.

    M%C3%A4dar%C3%B5igas - явно результат кодировки юникод строки, получается что для браузера слово Mädarõigas - не юникод, а что же тогда?


    > главное чтобы в "обратку" разворачивалось, а не соответствие
    > в браузере.


    В обратку нет проблем, UTF8Decode(HTTPDecode('M%C3%A4dar%C3%B5igas'))

    Блин где у меня пробел в образовании? ((
  • Mutilator (21.02.12 00:06) [6]
    то есть вопрос простой:

    как Mädarõigas превратить в M%E4dar%F5igas?

    это для тех кто запутался в рассуждениях
  • DVM © (21.02.12 00:16) [7]

    > HTTPEncode(UTF8Encode('Mädarõigas'))
    >
    > получаем
    >
    > M%C3%A4dar%C3%B5igas, что явно не соответствует преобразованию
    > в браузере.

    тебе шашечки или ехать? Сервер такой метод кодирования устраивает?
    Этих методов URL кодирования не один единственный и все корректные.
  • DVM © (21.02.12 00:25) [8]

    >  получается что для браузера слово Mädarõigas - не юникод,
    >  а что же тогда?

    не юникод, текст в однобайтной кодировке какой то национальной, типа 1251 но другой
  • sniknik © (21.02.12 00:45) [9]
    > как Mädarõigas превратить в M%E4dar%F5igas?
    да элементарно... вопрос только будет ли это юникодом на выходе п кодировке части символа...

    но, для тех кто не умеет думать -
    function HTTPEncode(const AStr: WideString): String;
    const
     NoConversion = ['A'..'Z','a'..'z','*','@','.','_','-','0'..'9','$','!','''','(',')'];
    var
     Sp: Char;
     Rp: string;
     i: integer;
    begin
     result:= '';
     Rp:= '000';
     for i:= 1 to Length(AStr) do begin
       Sp:= Char(Lo(Word(AStr[i])));
       if Sp in NoConversion
         then result:= result + Sp
         else
           if Sp = ' '
             then result:= result + '+'
             else begin
               FormatBuf(Rp[1], 3, '%%%.2x', 6, [Ord(Sp)]);
               result:= result + Rp;
             end;
     end;
    end;

    procedure TForm1.Button3Click(Sender: TObject);
    const
     s1: WideChar  = #$00E4;
     s2: WideChar  = #$00F5;
    var
     st: WideString;
    begin
     st:= WideString('M')+s1+'dar'+s2+'igas';
     RichEdit1.Lines.Add(HTTPEncode(st));
    end;



    удачи со "страшным монстром".
  • Mutilator (21.02.12 00:51) [10]

    > тебе шашечки или ехать? Сервер такой метод кодирования устраивает?

    Нет, сервер такую кодировку не понимает. Выводит Mädarõigas

    > Этих методов URL кодирования не один единственный и все
    > корректные.

    Что за глупость? вот заголовок к серверу

    ==========================================
    POST /search.html HTTP/1.1
    Host: www.host.com
    Connection: keep-alive
    Content-Length: 80
    Cache-Control: max-age=0
    User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11
    Content-Type: application/x-www-form-urlencoded
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
    Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.3

    search=M%E4dar%F5igas
    =================================================

    и как серверу понять каким именно образом раскручивать передаваемые данные, если в заголовке от браузера нет метода кодировки? Все декодирование стандартно и приводит всегда к одному и тому же результату. В моем случае в делфи я смог получить только M%C3%A4dar%C3%B5igas. что НЕВЕРНО.
  • ~AQUARIUS~ (21.02.12 01:16) [11]
    Попробуйте сначала закодировать строку в UTF-8, а потом делать HTTP-кодирование как обычно
  • Mutilator (21.02.12 01:19) [12]

    > удачи со "страшным монстром".


    Большое спасибо, рабочий вариант, сервер понимает Mädarõigas. Но теперь проблема с HU$TL? HA®D

    браузер кодирует эту строку как HU%24TL%80+HA%AED

    переделанная тобой функция кодирует в HU$TL%AC+HA%AED

    с долларом проблем нет. но что происходит с ? ?? почему она не верно кодируется?
  • Mutilator (21.02.12 01:20) [13]

    > Попробуйте сначала закодировать строку в UTF-8, а потом
    > делать HTTP-кодирование как обычно


    это я попробовал сразу, об этом писал выше, неверный результат
  • Омлет © (21.02.12 08:00) [14]
    Дай ссылку на страницу. Похоже там кодировка не windows-1251.
  • Омлет © (21.02.12 08:02) [15]
    > и как серверу понять каким именно образом раскручивать передаваемые данные, если в заголовке от браузера нет метода кодировки?

    Сервер сам говорит в какой кодировке должны быть данные из форм.
  • sniknik © (21.02.12 08:19) [16]
    > почему она не верно кодируется?
    причина не в функции, а в логике, кодировка тут однобайтная про что говорили, сервер судя по всему, раз понимает, ждет такую же. а вот преобразование из "той" кодировки в юникод, и после кривое кодирование с обрезанием одного символа дает то что есть...
    хотя что тебе объяснять, ты же не желаешь рассуждать.

    а функция как можно убедится может и то и то (2 символа правильный и "не правильный" соседствуют)
    procedure TForm1.Button3Click(Sender: TObject);
    const
     s1: WideChar  = #$00E4;
     s2: WideChar  = #$00F5;
     s3: WideChar  = #$0080;
     s4: WideChar  = #$00AC;
    var
     st: WideString;
    begin
     st:= WideString('M')+s1+s2+s3+s4;
     RichEdit1.Lines.Add(HTTPEncode(st));
    end;


    хотя, они оба уже неправильные, отображение в нашей раскладке (как пример в [3]) у обоих "не то" - "А" и "м".
  • Anatoly Podgoretsky © (21.02.12 10:37) [17]

    > M%C3%A4dar%C3%B5igas - явно результат кодировки юникод строки,
    >  получается что для браузера слово Mädarõigas - не юникод,
    >  а что же тогда?

    Пробел в том, что Интернет, он ASCII даже не ANSI, и тем более не UNICODE


    > function HTTPEncode(const AStr: String): string;
    >
    > C++ syntax:
    >
    > extern PACKAGE AnsiString __fastcall HTTPEncode(const AnsiString
    > AStr);


    AStr: String это AnsiString
    Поставь Эстонский для не Юникод программ, все будет работать, или как сказали, тебе нужно Д2009+, или не используй в URL не английских букв
  • Anatoly Podgoretsky © (21.02.12 10:38) [18]
    gas пишется как gaas
  • Mutilator (21.02.12 13:48) [19]

    > Поставь Эстонский для не Юникод программ


    о чем речь?
    > не используй в URL не английских букв


    это не для урл, это для отправки данных пост запросом


    > хотя что тебе объяснять, ты же не желаешь рассуждать


    напротив с удовольствием порассуждаю и послушаю, только кроме критики ничего пока не вижу ( а разобраться надо.
    > Дай ссылку на страницу. Похоже там кодировка не windows-
    > 1251.


    в исходном коде действительно

    <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">

    как работать с 1252? мы ближе к истине? ))
  • Anatoly Podgoretsky © (21.02.12 13:56) [20]
    > Mutilator  (21.02.2012 13:48:19)  [19]

    POST запрос надо отсылать в Base64
  • Anatoly Podgoretsky © (21.02.12 13:57) [21]

    > <meta http-equiv="Content-Type" content="text/html; charset=windows-
    > 1252">

    Это не эстонская кодировка
  • Mutilator (21.02.12 14:21) [22]

    > POST запрос надо отсылать в Base64


    ну причем же тут Base64 ?

    если Mädarõigas завернуть в base64 получим TWFkYXJvaWdhcw==
    если HU$TL? HA®D завернуть в base64 получим SFUkVEyIIEhBrkQ=

    а должно быть как посылает в браузер:

    Mädarõigas = M%E4dar%F5igas
    HU$TL? HA®D = HU%24TL%80+HA%AED
  • Mutilator (21.02.12 14:23) [23]
    теперь стало ясно что мы имеем дело с windows-1252, как зная это правильно закодировать WidsString?
  • Омлет © (21.02.12 14:51) [24]
  • Омлет © (21.02.12 15:05) [25]
    И, наверное, надо выставить ANSI_CHARSET для едита, откуда приходит текст.
  • Anatoly Podgoretsky © (21.02.12 15:08) [26]
    > Mutilator  (21.02.2012 14:21:22)  [22]

    Это ANSI а не Unicode
  • Anatoly Podgoretsky © (21.02.12 15:16) [27]
    > Mutilator  (21.02.2012 14:23:23)  [23]

    Какие у тебя настройки для не Юникод программ
  • Mutilator (21.02.12 16:10) [28]

    > Какие у тебя настройки для не Юникод программ


    о чем речь? настройки в винде?
  • sniknik © (21.02.12 17:59) [29]
    > о чем речь? настройки в винде?
    ага, чтобы правильно работало не нужно преобразовывать в бникод, нужно взять как есть ANSI строку, и как есть ее конвертировать, но только под той же локалью что исходная, откуда копируешь. т.е.
    > <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
    дожна быть она же. (правда тогда весь интерфейс "скракозяблиться" но ... )
    можно кстати попробовать установить локаль перед конвертацией и возвращать после... но, для этого нужно как то понимать, что ты делаешь, откуда и как текст берешь. тест короче нужен, а не обрывки "тайных знаний". ну или сам.
  • Mutilator (21.02.12 22:58) [30]
    мне нужно чтобы работала под любой виндой независимо от настроек
  • sniknik © (21.02.12 23:14) [31]
    и это все, что есть сказать? ну тогда точно сам.
  • DVM © (21.02.12 23:17) [32]

    > Mutilator   (21.02.12 00:51) [10]
    >
    > > тебе шашечки или ехать? Сервер такой метод кодирования
    > устраивает?
    >
    > Нет, сервер такую кодировку не понимает. Выводит Mädarõigas
    >
    > > Этих методов URL кодирования не один единственный и все
    >
    > > корректные.
    >
    > Что за глупость? вот заголовок к серверу


    > и как серверу понять каким именно образом раскручивать передаваемые
    > данные, если в заголовке от браузера нет метода кодировки?
    >

    Может сначала почитал бы про URL кодирование что-то прежде чем бросаться словами "глупость и прочее". Представь себе, серверу зачастую приходится угадывать, в какой кодировке к нему поступили URL кодированные данные. Почему? Все очень просто. Допустим, серверу пердана последовательность %EA%EE% (здесь два символа к и о) - эти 2 байта с одинаковым успехом могут представлять собой как 1 символ UTF8 так и 2 символа ANSI. С помощью специальных статистических (и иных) методов большинство серверов умеет определять что реально было закодировано. Другой вариант кодирования, когда двухбайтные символы кодируются как  %u043A%u043E (здесь два символа к и о). Есть еще третий вариант, который описывать не буду.
  • DVM © (21.02.12 23:23) [33]

    > Mutilator   (21.02.12 14:23) [23]
    > теперь стало ясно что мы имеем дело с windows-1252, как
    > зная это правильно закодировать WidsString?

    Конвертировать в нужную локаль с помощью WideStringToMultibyte и потом получившийся набор байт URL кодировать. Наверное так.
  • DVM © (21.02.12 23:24) [34]

    > WideStringToMultibyte

    WideCharToMultibyte то есть
  • Anatoly Podgoretsky © (22.02.12 09:43) [35]
    > Mutilator  (21.02.2012 22:58:30)  [30]

    Без настроек когда это Unicode и у сервера правильная кодировка или utf08
    или 1256
  • Mutilator (29.02.12 22:16) [36]
    задача решена фрилансером за 30 секунд, вот рецепт:

    uses TntSystem;
    .......

    ShowMessage(HTTPEncode(WideStringToStringEx(edt.Text, 1252)));

    где edt - tntEdit
  • sniknik © (29.02.12 23:16) [37]
    какие длинные 30 секунд получились... :)
    а там ты тоже начал с того, что здесь, или с выясненного здесь - "нужно из юникода получить url кодирование в 1252"?
  • Anatoly Podgoretsky © (01.03.12 10:34) [38]
    Задача не решена, а временно замаскировано, непрофессиональная работа
  • DVM © (01.03.12 22:12) [39]

    > Mutilator   (29.02.12 22:16) [36]

    если бы вдумался в написанное мной в [33] то может не понадобился бы ни фриленсер, ни модуль TNTSystem.
 
Конференция "Сети" » HTTPEncode для WideString ? [D7, WinXP]
Есть новые Нет новых   [134435   +14][b:0][p:0.002]