Pergunta

Estou com um problema que não sei como resolver.

Eu tenho um servidor HTTP Indy10.Usei servidores HTTP Indy9 e Indy10 em muitas aplicações e nunca tive problemas.Mas agora estou usando o servidor HTTP Indy10 com estrutura ExtJS javascript RAI.

O problema é quando envio dados que contêm caracteres não-Ansi.Por exemplo, quando envio a carta "č", que é uma carta na página de código 1250 (esloveno, croata...), recebo o seguinte em Indy em "parâmetros não analisados" -> "%C4%8D".Esta é a representação hexadecimal correta da letra "č" na codificação utf-8.Todas as minhas páginas são utf-8 e nunca tive problemas para enviar dados de formulário para o Indy.Depurei o código e vi que realmente obtive uma sequência de bytes como esta:[37, 67, 52, 37, 56, 68].Esta é a representação de bytes da string "%C4%8D".Mas é claro que Indy não consegue codificar isso corretamente para UTF-16.Então, como exemplo.O campo do formulário real:

FirstName=črt

sai assim quando enviado:

FirstName=%C4%8Drt

Não sei como resolver isso.Eu olhei nos fóruns do ExtJS, mas não há nada sobre esse assunto.Alguém sabe alguma coisa sobre esse tipo de problema?

EDITAR:

Se eu codificar parâmetros para JSON, eles chegarão corretamente.Também tentei decodificar URL os parâmetros, mas o resultado não está correto.Talvez eu tenha perdido alguma coisa.Vou olhar para isso novamente.E sim, parece que o URL ExtJS codifica os parâmetros

EDITAR2:

Ok, descobri mais.Comparei o conteúdo real dos dados da postagem.É assim:

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

Em ambos os casos, os parâmetros não analisados ​​são idênticos.Eu tenho parseparams ligados e no BDS2006 eles são analisados ​​corretamente, mas em 2010 eles não estão.Este é o Indy10 repleto de delphi.Existe um bug nesta versão ou estou fazendo algo errado?

EDITAR3:

Eu baixei a versão noturna mais recente do Indy10.Ainda o mesmo problema.

EDITAR4:

Sou forçado a aceitar minha própria resposta.

Foi útil?

Solução

Para responder sobre este assunto.

Definitivamente, isso não está funcionando como deveria em Unicode.Indy usa strings Unicode internamente.O problema é quando os parâmetros são decodificados para TStringList.O problema é a linha:

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

encontrado em "TIdHTTPRequestInfo.DecodeAndSetParams".Ele não decodifica parâmetros corretamente, provavelmente porque está funcionando em strings Unicode.

A solução alternativa que encontrei é usar "HTTPDecode" de "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;

Mas não posso acreditar que uma tarefa tão comum não esteja funcionando corretamente.Alguém pode confirmar que isso é realmente um bug ou estou apenas fazendo algo errado?

Outras dicas

Parece que a string está codificada em URL, então você usa o seguinte código para decodificar:

uses
  idURI;

value := TIdURI.URLDecode( value );

editar

Parece que há um caso em que o decodificador não decodifica corretamente os bytes duplos como um único caractere.Olhando para a fonte, parece que ele seria decodificado corretamente se o caractere fosse codificado como% UC48D, mas em meus testes isso ainda não foi decodificado corretamente.O interessante é que a função TidURI.ParamsEncode gera a codificação adequada, mas essa codificação não é reversível usando as rotinas adequadas na versão mais recente do Indy 10.

Estou usando Delphi 7 e migro para Indy 10.Encontrei provável problema com caracteres portugueses e resolvo alterando a fonte abaixo:

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

fim;

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top