HTTP-сервер Delphi indy10 и отправка формы ExtJS - PullRequest
5 голосов
/ 04 марта 2010

У меня есть проблема, которую я не знаю, как решить.

У меня есть HTTP-сервер Indy10. Я использовал HTTP-серверы Indy9 и Indy10 во многих приложениях, и у меня никогда не было проблем. Но сейчас я использую HTTP-сервер Indy10 с инфраструктурой RAI ExtJS javascript.

Проблема заключается в том, что я отправляю данные, содержащие неанси-символы. Например, когда я отправляю букву "č", которая является буквой в кодовой странице 1250 (словенский, хорватский ...), я получаю следующее в Indy под "unparsed params" -> "% C4% 8D". Это правильное шестнадцатеричное представление буквы "č" в кодировке utf-8. Все мои страницы - utf-8, и у меня никогда не было проблем с отправкой данных формы в Indy. Я отладил код и увидел, что на самом деле получаю последовательность байтов, подобную этой: [37, 67, 52, 37, 56, 68]. Это байтовое представление строки "% C4% 8D". Но, конечно, Indy не может правильно закодировать это в UTF-16. Так что в качестве примера. Фактическое поле формы:

FirstName=črt

выглядит так, когда отправлено:

FirstName=%C4%8Drt

Я не знаю, как это решить. Я смотрел форумы ExtJS, но по этой теме ничего нет. Кто-нибудь знает что-нибудь об этой проблеме?

EDIT

Если я закодирую params и JSON, они приходят правильно. Я также пытался URL-адрес декодировать параметры, но результат не является правильным. Может быть, я что-то пропустил. Я посмотрю на это снова. И да, кажется, что ExtJS URL кодирует параметры

EDIT2

Хорошо, я обнаружил больше. Я сравнил фактическое содержание данных поста. Это так:

Delphi 2006 (Indy10): FirstName=%C4%8D
Delphi 2010 (Indy10): FirstName=%C4%8D

В обоих случаях неразобранные параметры идентичны. У меня есть ParseParams включен и в BDS2006 они правильно разобраны, а под 2010 их нет. Это Indy10, набитый дельфи. В этой версии есть ошибка или я что-то не так делаю?

EDIT3

Я скачал последнюю ночную сборку Indy10. Все та же проблема.

EDIT4

Я вынужден принять собственный ответ.

Ответы [ 3 ]

4 голосов
/ 04 марта 2010

Ответить на эту тему.

Это определенно не работает, как это должно быть в Unicode. Indy использует строки Юникода для внутреннего использования. Проблема в том, когда параметры декодируются в TStringList. Проблема в линии:

Params.Add(TIdURI.URLDecode(s));

найдено в "TIdHTTPRequestInfo.DecodeAndSetParams". Он неправильно декодирует параметры, возможно потому, что работает над строками Unicode.

Обходной путь, который я нашел, заключается в использовании «HTTPDecode» из «HTTPApp.pas».

Params := TStringList.Create;
try
  Params.StrictDelimiter := True;
  Params.Delimiter := '&';

  // parse the parameters and store them into temporary string list
  Params.DelimitedText := UTF8ToString(HTTPDecode(UTF8String(Request.UnparsedParams)));
  // do something with params... 
finally
  Params.Free;
end;

Но я не могу поверить, что такая общая задача работает неправильно. Может кто-нибудь подтвердить, что это действительно ошибка или я просто что-то не так делаю?

1 голос
/ 06 января 2011

Я использую Delphi 7 и мигрирую в Indy 10. Я обнаружил вероятную проблему с португальскими символами и решил эту проблему, изменив источник ниже:

procedure TIdHTTPRequestInfo.DecodeAndSetParams(const AValue: String);
  ...
  //Params.Add(TIdURI.URLDecode(s)); //-- UTF8 supose
  Params.Add(TIdURI.URLDecode(s,TIdTextEncoding.Default)); //-- ASCII worked
  ...

конец;

1 голос
/ 04 марта 2010

Похоже, что строка закодирована в URL, поэтому вы используете следующий код для декодирования:

uses
  idURI;

value := TIdURI.URLDecode( value );

edit

Похоже, есть случай, когдадекодер неправильно декодирует двойные байты как один символ.Глядя на источник, кажется, что он будет правильно декодироваться, если символ закодирован как% UC48D, но в моем тестировании это все еще не декодируется должным образом.Что интересно, так это то, что функция TidURI.ParamsEncode генерирует правильную кодировку, но эта кодировка необратима с использованием соответствующих подпрограмм в последней версии Indy 10.

...