我有一个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中我错过的一个错误吗?
答案 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。