使用单元LazUTF8时TIdURI.URLDecode的结果错误

时间:2019-02-11 12:41:36

标签: http utf-8 indy lazarus freepascal

使用Free Pascal 3.0.4,此测试程序可以正确编写ÄÖÜ

program FPCTest;

uses IdURI;

begin
  WriteLn(TIdURI.URLDecode('%C3%84%C3%96%C3%9C'));
  ReadLn;
end.

但是,如果使用单元LazUTF8(如here所述),则会写入 ???

program FPCTest;

uses IdURI, LazUTF8;

begin
  WriteLn(TIdURI.URLDecode('%C3%84%C3%96%C3%9C'));
  ReadLn;
end.

对于使用LazUTF8的程序,如何解决此解码错误?

2 个答案:

答案 0 :(得分:2)

String类型是AnsiString 1 的别名时,Indy的许多功能都公开了额外的参数/属性,以使用户可以控制{{ 1}}值在执行AnsiString转换的操作中传递。

1:Delphi 2009之前的版本,以及未使用AnsiString<->byte{$ModeSwitch UnicodeStrings}的FreePascal / Lazarus(仅供参考,Indy 11将使用它们!)。

在大多数情况下,Indy的默认字节编码为ASCII(因为Indy最初实现的许多Internet协议仅支持ASCII-每个Indy组件都会根据协议将其自身升级为UTF),尽管有些东西使用了OS默认代码页/字符集。

可以通过在{$Mode DelphiUnicode}单位中设置全局GIdDefaultTextEncoding变量来在运行时更改Indy的默认字节编码,例如:

IdGlobal

但是,在这种特殊情况下,GIdDefaultTextEncoding := encUTF8; 不使用TIdURI.URLEncode(),但是它确实具有可选的GIdDefaultTextEncoding参数,您可以使用该参数为返回的{ {1}}(除了可选的ADestEncoding参数,用于指定已解析的网址八位字节的字节编码-默认情况下为UTF-8),例如:

AnsiString

上面的代码会将URL编码的八位字节解析为UTF-8,然后以UTF-8编码的AByteEncoding原样返回该数据。

如果未为TIdURI.URLDecode('%C3%84%C3%96%C3%9C' {$IFNDEF FPC_UNICODESTRINGS}, IndyTextEncoding_UTF8, IndyTextEncoding_UTF8{$ENDIF} ) 指定输出编码,则AnsiString默认为操作系统默认值。如果您希望它改用ADestEncoding,请在URLDecode()参数中指定GIdDefaultTextEncoding

IndyTextEncoding_Default

另一种选择是将ADestEncoding函数用于TIdURI.URLDecode('%C3%84%C3%96%C3%9C' {$IFNDEF FPC_UNICODESTRINGS}, IndyTextEncoding_UTF8, IndyTextEncoding_Default{$ENDIF} ) ,并向其传递FreePascal的DefaultSystemCodePage变量,该变量由IndyTextEncoding(CodePage)包设置为ADestEncoding > 2 :

LazUtils

2:Indy的问题跟踪器中有opened a ticket,可以在为FreePascal / Lazarus进行编译时添加对CP_UTF8的支持。

答案 1 :(得分:0)

在TIdURI.URLDecode中进行此更改后,可以使用386ff LazUTF8行:

range

注释

此更改假设始终使用LazUTF8单元,并且每次使用新版本时都需要应用Indy源代码更改。

我还发现没有办法在有和没有LazUTF8的情况下都可以修复TIdURI.URLDecode。