我有一个 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 中我错过的错误吗?
最佳答案
在XE2中,字符串是Unicode的。当TIdHTTPServer
解码ARequestInfo.Document
在D2009及更高版本中,它需要将百分比编码的数据解码为UTF-8编码的数据,然后将其解码为最终的Unicode字符串。目前没有选项可以更改它(我已向我们的问题跟踪器提交了功能请求)。 %F6
不代表有效的 UTF-8 八位字节,这就是为什么你最终得到 '?'
。在 UTF-8 中,'ö'
字符将被 UTF-8 编码为 $C3 $B6
因此百分比编码为 %C3%B6
,不是%F6
.
在 D2007 中,字符串为 Ansi。当TIdHTTPServer
解码ARequestInfo.Document
在 D2007 及更早版本中,它按原样提供解码数据,因此 %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
将数据转换为您最初期望的 Ansi 值。在 D009+ 中,这是自动为您处理的。
顺便说一句,直接在 OnCommandGet
中访问 UI 组件事件不是线程安全的。您必须与主线程同步才能安全地访问 UI。
关于delphi - TidHttpServer (Delphi XE2) 可以处理 urlencoded 字符吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12841377/