-
не пойму каким образом корректно конвертировать WideString строку (Mädarõigas) для правильной отправки POST запросом по HTTP. Браузер конвертирует ее в
M%E4dar%F5igas
Используя стандартную библиотеку HTTPApp и ее функцию HTTPEncode теряем WideString и на выходе получаем Madaroigas. Если приводить перед конвертацией строку к UTF8
HTTPEncode(UTF8Encode('Mädarõigas'))
получаем
M%C3%A4dar%C3%B5igas, что явно не соответствует преобразованию в браузере.
Бьюсь над этим вопросом вторые сутки помогите кодом.
-
надо на D2009 и больше переходить... там HTTPEncode с юникодом должна быть. ... наверное.
-
Такое решение очевидно, но не подходит.
-
> M%C3%A4dar%C3%B5igas, что явно не соответствует преобразованию в браузере. главное чтобы в "обратку" разворачивалось, а не соответствие в браузере.
кстати браузер может только показывает так, а на деле даже не кодирует... > M%E4dar%F5igas вот не похоже на юникод... однобайтный %E4 - 228 - ф %F5 - 245 - ї
-
если только раскодировать с учетом, что это точно юникод... и первый байт добавлять. х.з. как оно там делает. если так то вполне можно свою функцию "asбраузер" написать...
-
M%E4dar%F5igas получено сниффером непосредственно с HTTP. тут ошибки точно нет. Причем все браузеры кодируют именно так. Просто не понятно почему такие важные и казалось бы простые вещи так трудно реализовать в делфи (.
M%C3%A4dar%C3%B5igas - явно результат кодировки юникод строки, получается что для браузера слово Mädarõigas - не юникод, а что же тогда?
> главное чтобы в "обратку" разворачивалось, а не соответствие > в браузере.
В обратку нет проблем, UTF8Decode(HTTPDecode('M%C3%A4dar%C3%B5igas'))
Блин где у меня пробел в образовании? ((
-
то есть вопрос простой:
как Mädarõigas превратить в M%E4dar%F5igas?
это для тех кто запутался в рассуждениях
-
> HTTPEncode(UTF8Encode('Mädarõigas')) > > получаем > > M%C3%A4dar%C3%B5igas, что явно не соответствует преобразованию > в браузере.
тебе шашечки или ехать? Сервер такой метод кодирования устраивает? Этих методов URL кодирования не один единственный и все корректные.
-
> получается что для браузера слово Mädarõigas - не юникод, > а что же тогда?
не юникод, текст в однобайтной кодировке какой то национальной, типа 1251 но другой
-
> как 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; удачи со "страшным монстром".
-
> тебе шашечки или ехать? Сервер такой метод кодирования устраивает?
Нет, сервер такую кодировку не понимает. Выводит 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. что НЕВЕРНО.
-
Попробуйте сначала закодировать строку в UTF-8, а потом делать HTTP-кодирование как обычно
-
> удачи со "страшным монстром".
Большое спасибо, рабочий вариант, сервер понимает Mädarõigas. Но теперь проблема с HU$TL? HA®D
браузер кодирует эту строку как HU%24TL%80+HA%AED
переделанная тобой функция кодирует в HU$TL%AC+HA%AED
с долларом проблем нет. но что происходит с ? ?? почему она не верно кодируется?
-
> Попробуйте сначала закодировать строку в UTF-8, а потом > делать HTTP-кодирование как обычно
это я попробовал сразу, об этом писал выше, неверный результат
-
Дай ссылку на страницу. Похоже там кодировка не windows-1251.
-
> и как серверу понять каким именно образом раскручивать передаваемые данные, если в заголовке от браузера нет метода кодировки?
Сервер сам говорит в какой кодировке должны быть данные из форм.
-
> почему она не верно кодируется? причина не в функции, а в логике, кодировка тут однобайтная про что говорили, сервер судя по всему, раз понимает, ждет такую же. а вот преобразование из "той" кодировки в юникод, и после кривое кодирование с обрезанием одного символа дает то что есть... хотя что тебе объяснять, ты же не желаешь рассуждать. а функция как можно убедится может и то и то (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]) у обоих "не то" - "А" и "м".
-
> 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 не английских букв
-
gas пишется как gaas
-
> Поставь Эстонский для не Юникод программ
о чем речь? > не используй в URL не английских букв
это не для урл, это для отправки данных пост запросом
> хотя что тебе объяснять, ты же не желаешь рассуждать
напротив с удовольствием порассуждаю и послушаю, только кроме критики ничего пока не вижу ( а разобраться надо. > Дай ссылку на страницу. Похоже там кодировка не windows- > 1251.
в исходном коде действительно
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
как работать с 1252? мы ближе к истине? ))
-
> Mutilator (21.02.2012 13:48:19) [19]
POST запрос надо отсылать в Base64
-
> <meta http-equiv="Content-Type" content="text/html; charset=windows- > 1252">
Это не эстонская кодировка
-
> 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
-
теперь стало ясно что мы имеем дело с windows-1252, как зная это правильно закодировать WidsString?
-
-
И, наверное, надо выставить ANSI_CHARSET для едита, откуда приходит текст.
-
> Mutilator (21.02.2012 14:21:22) [22]
Это ANSI а не Unicode
-
> Mutilator (21.02.2012 14:23:23) [23]
Какие у тебя настройки для не Юникод программ
-
> Какие у тебя настройки для не Юникод программ
о чем речь? настройки в винде?
-
> о чем речь? настройки в винде? ага, чтобы правильно работало не нужно преобразовывать в бникод, нужно взять как есть ANSI строку, и как есть ее конвертировать, но только под той же локалью что исходная, откуда копируешь. т.е. > <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> дожна быть она же. (правда тогда весь интерфейс "скракозяблиться" но ... ) можно кстати попробовать установить локаль перед конвертацией и возвращать после... но, для этого нужно как то понимать, что ты делаешь, откуда и как текст берешь. тест короче нужен, а не обрывки "тайных знаний". ну или сам.
-
мне нужно чтобы работала под любой виндой независимо от настроек
-
и это все, что есть сказать? ну тогда точно сам.
-
> Mutilator (21.02.12 00:51) [10] > > > тебе шашечки или ехать? Сервер такой метод кодирования > устраивает? > > Нет, сервер такую кодировку не понимает. Выводит Mädarõigas > > > Этих методов URL кодирования не один единственный и все > > > корректные. > > Что за глупость? вот заголовок к серверу
> и как серверу понять каким именно образом раскручивать передаваемые > данные, если в заголовке от браузера нет метода кодировки? >
Может сначала почитал бы про URL кодирование что-то прежде чем бросаться словами "глупость и прочее". Представь себе, серверу зачастую приходится угадывать, в какой кодировке к нему поступили URL кодированные данные. Почему? Все очень просто. Допустим, серверу пердана последовательность %EA%EE% (здесь два символа к и о) - эти 2 байта с одинаковым успехом могут представлять собой как 1 символ UTF8 так и 2 символа ANSI. С помощью специальных статистических (и иных) методов большинство серверов умеет определять что реально было закодировано. Другой вариант кодирования, когда двухбайтные символы кодируются как %u043A%u043E (здесь два символа к и о). Есть еще третий вариант, который описывать не буду.
-
> Mutilator (21.02.12 14:23) [23] > теперь стало ясно что мы имеем дело с windows-1252, как > зная это правильно закодировать WidsString?
Конвертировать в нужную локаль с помощью WideStringToMultibyte и потом получившийся набор байт URL кодировать. Наверное так.
-
> WideStringToMultibyte
WideCharToMultibyte то есть
-
> Mutilator (21.02.2012 22:58:30) [30]
Без настроек когда это Unicode и у сервера правильная кодировка или utf08 или 1256
-
задача решена фрилансером за 30 секунд, вот рецепт:
uses TntSystem; .......
ShowMessage(HTTPEncode(WideStringToStringEx(edt.Text, 1252)));
где edt - tntEdit
-
какие длинные 30 секунд получились... :) а там ты тоже начал с того, что здесь, или с выясненного здесь - "нужно из юникода получить url кодирование в 1252"?
-
Задача не решена, а временно замаскировано, непрофессиональная работа
-
> Mutilator (29.02.12 22:16) [36]
если бы вдумался в написанное мной в [33] то может не понадобился бы ни фриленсер, ни модуль TNTSystem.
|