TidHttpServer(Delphi XE2)可以处理urlencoded字符吗?

时间:2012-10-11 14:01:44

标签: delphi delphi-xe2 indy

我有一个TidHttpServer使用以下代码监听端口8844:

procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  if ARequestInfo.Document <> '/favicon.ico' then
  begin
    Memo1.Text := ARequestInfo.Params.Text;
  end;
end;

这是使用Delphi XE2编译的。当我浏览

http://localhost:8844/document?Value=%F6   <-- %F6 is the encoded value for ö

......我得到了结果:

value=?

如果我使用Delphi 2007编译应用程序,我会得到以下结果

value=ö

这是Indy中我错过的一个错误吗?

1 个答案:

答案 0 :(得分:5)

在XE2中,字符串是Unicode。当TIdHTTPServer解码D2009及更高版本中的ARequestInfo.Document时,它需要将百分比编码数据解码为UTF-8编码数据,然后将其解码为最终的Unicode字符串。目前没有更改的选项(我已向我们的问题跟踪器提交了功能请求)。 %F6不代表有效的UTF-8八位字节,这就是您最终使用'?'的原因。在UTF-8中,'ö'字符将被UTF-8编码为$C3 $B6,因此百分比编码为%C3%B6,而不是%F6

在D2007中,字符串是Ansi。当TIdHTTPServer解码D2007及更早版本中的ARequestInfo.Document时,它按原样提供解码数据,因此%F6将解码为$F6并存储为#246 。然后,RTL使用本地计算机的默认Ansi代码页来解释该值,因此它仅代表定义它的Ansi代码页的'ö'字符(Windows-1252和ISO-8859-1,但ISO-8859-5没有,例如)。

我建议您更改服务器逻辑,以便在两个Delphi版本中使用UTF-8编码的URL。在D2007中,您可以使用RTL的UTF8Decode()函数将UTF-8编码的AnsiString解码为WideString,然后您可以将其分配给另一个AnsiString以转换数据进入你最初期待的安西价值。在D009 +中,将自动为您处理。

另外,在OnCommandGet事件中直接访问UI组件不是线程安全的。您必须与主线程同步才能安全地访问UI。