我收到POST请求时收到的JSON字符串有问题。目前这是我读它的方式:
procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
Stream : TStream;
S : string;
begin
If ARequestInfo.Command = 'POST' then
begin
Stream := ARequestInfo.PostStream;
if assigned(Stream) then
begin
Stream.Position := 0;
S := UTF8ToAnsi(ReadStringFromStream(Stream));
end;
end;
end;
我单独尝试了ReadStringFromStream()
和UTF8ToAnsi()
and AnsiToUTF8()
,但我一直看到这样的字符串:
'[' #$ A#9 '{' #$ A#9#9 ' “测试”: “BB”,' #$ A#9#9 ' “测试”: “AA”' #$ A#9' } '#$ A']”
我知道它与编码有关,但我不知道如何解决它。
你知道哈希(#)符号表示一个字符值,而美元($)符号表示十六进制值,是吗?因此,#$A
表示字符十进制10,恰好表示NewLine
和#9
表示字符9,这是TAB
字符。返回字符串中没有任何意外。如果你把它喂成一个理解NewLine
而没有前面的CarriageReturn
的东西,它可能看起来像你预期的那样。
例如,调试器使用#-syntax表示无法以其他方式表示的字符。
您在示例中显示的数据非常精细,正如Tom B所解释的那样。您正在查看调试器中的字符串数据,其中#A
是换行符,#9
是制表符,因此实际字符串如下所示:
[ { "test":"bb", "test":"aa" } ]
哪个是有效的JSON。
但是,您阅读数据的方式并不正确,尤其是如果您使用的是Unicode版本的Delphi(2009+)。您没有将任何值传递给AByteEncoding
的ReadStringFromString()
参数,因此它将使用Indy的默认编码对流字节进行解码,默认情况下为7位US-ASCII(请参阅GIdDefaultTextEncoding
单元中的IdGlobal
变量)。 JSON默认使用UTF-8,因此如果JSON包含任何非ASCII字符,则会损坏JSON。在事实之后使用UTF8ToAnsi()
将无法解决这个问题。
你的代码应该是这样的:
procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
Stream : TStream;
S : string;
begin
If ARequestInfo.CommandType = hcPOST then
begin
Stream := ARequestInfo.PostStream;
if Assigned(Stream) then
begin
S := ReadStringFromStream(Stream, -1, IndyTextEncoding_UTF8);
end
end
end;
这告诉Indy将流字节解码为UTF-8到UTF-16,然后返回解码后的字符串(如果您使用的是非Unicode版本的Delphi,UTF-16数据将在退出时转换为ANSI,受制于ADestEncoding
的可选ReadStringFromStream()
参数。