Servidor http Delphi indy10 e envio de formulário ExtJS
-
24-09-2019 - |
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.
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;