Delphi 使用Indy 10接收Unicode字符串

Delphi 使用Indy 10接收Unicode字符串,delphi,unicode,indy,indy10,delphi-10.4-sydney,Delphi,Unicode,Indy,Indy10,Delphi 10.4 Sydney,我正在使用最新的Delphi 10.4.2和Indy 10 在REST服务器中,接收并处理JSON命令。除了Unicode之外,它工作正常 一个简单的JSON,如下所示: {“driverNote”:“Test”} 显示正确 如果我现在更改为Unicode俄语字符: {“驱动器注释”:“Саааа”} 我不确定我应该从哪里开始追踪这个。我希望ARequestInfo.FormParams在调试器中与s变量具有相同的值 如果我调试Indy本身,FormParams在此代码中设置: if L

我正在使用最新的Delphi 10.4.2和Indy 10

在REST服务器中,接收并处理JSON命令。除了Unicode之外,它工作正常

一个简单的JSON,如下所示:

{“driverNote”:“Test”}
显示正确

如果我现在更改为Unicode俄语字符:

{“驱动器注释”:“Саааа”}

我不确定我应该从哪里开始追踪这个。我希望
ARequestInfo.FormParams
在调试器中与
s
变量具有相同的值

如果我调试Indy本身,
FormParams
在此代码中设置:

if LRequestInfo.PostStream <> nil then
begin
  // decoding percent-encoded octets and applying the CharSet is handled by
  // DecodeAndSetParams() further below...
  EnsureEncoding(LEncoding, enc8Bit);
  LRequestInfo.FormParams := 
    ReadStringFromStream( LRequestInfo.PostStream, 
                          -1, 
                          LEncoding
                          {$IFDEF STRING_IS_ANSI}, LEncoding{$ENDIF});
  DoneWithPostStream(AContext, LRequestInfo); // don't need the PostStream anymore
end;
如果LRequestInfo.PostStream为零,则
开始
//解码百分比编码的八位字节并应用字符集由
//DecodeAndSetParams()位于下面。。。
确保重新编码(LEncoding,enc8Bit);
LRequestInfo.FormParams:=
ReadStringFromStream(LRequestInfo.PostStream,
-1, 
透镜编码
{$IFDEF STRING_IS_ANSI},LEncoding{$ENDIF});
DoneWithPostStream(AContext,LRequestInfo);//不再需要PostStream了
结束;
它使用
enc8Bit
。但是我的字符串有16位字符


这在Indy中处理不正确吗?

您从
IdCustomHTTPServer.pas中引用的代码片段不是Indy中的代码片段

在官方代码中,
TIdHTTPServer
不会将
PostStream
解码为
FormParams
,除非
ContentType
'application/x-www-form-urlencoded'

如果LRequestInfo.PostStream为nil,则开始
如果TextIsName(LContentType,ContentTypeFormUrlencoded),则
开始
//解码百分比编码的八位字节并应用字符集由下面的DecodeAndSetParams()处理。。。
确保重新编码(LEncoding,enc8Bit);
LRequestInfo.FormParams:=ReadStringFromStream(LRequestInfo.PostStream,-1,LEncoding{$IFDEF STRING_IS_ANSI},LEncoding{$ENDIF});
DoneWithPostStream(AContext,LRequestInfo);//不再需要PostStream了
结束;
结束;
那个
ContentType
检查是在2010年添加的,所以我不知道为什么它没有出现在您的版本中

在您的示例中,
ContentType
'application/json'
,因此原始json应该在
PostStream
中,而
FormParams
应该为空

也就是说,在您的Indy版本中,
TIdHTTPServer
只是从
PostStream
读取原始字节,并将每个字节零扩展到
FormParams
中的16位字符。要恢复原始字节,只需将每个
字符
截断为8位
字节
。例如,您可以在
IdGlobal
单元中使用Indy的
ToBytes()
函数,指定
enc8Bit
/
IndyTextEncoding_8Bit
作为字节编码


JSON最常见的传输方式是UTF-8(在您的示例中就是这种情况),因此当您可以访问任何版本的原始字节时,请确保将JSON字节解析为UTF-8。

Ok,您是正确的。我们的版本经过修补,json在contenttype中分配