如何解决使用 Indy 10 接收 Unicode 字符串
我使用的是最新的 Delphi 10.4.2 和 Indy 10。
在 REST 服务器中,接收和处理 JSON 命令。除了 Unicode,它工作正常。
像这样的简单 JSON:
{"driverNote": "Test"}
正确显示
如果我现在更改为 Unicode 俄语字符:
{"driverNote": "Статья"}
不知道我应该从哪里开始跟踪这个。我希望 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;
它使用 enc8Bit
。但我的字符串有 16 位字符。
这在 Indy 中处理不正确吗?
解决方法
您从 IdCustomHTTPServer.pas
中引用的代码片段不是 Indy 的 GitHub repo 中的内容。
在官方代码中,除非TIdHTTPServer
是PostStream
,否则FormParams
不会将ContentType
解码为'application/x-www-form-urlencoded'
:
if LRequestInfo.PostStream <> nil then begin
if TextIsSame(LContentType,ContentTypeFormUrlencoded) 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;
end;
那个 ContentType
检查是在 2010 年添加的,所以我不知道为什么它没有出现在您的版本中。
在您的示例中,ContentType
是 'application/json'
,因此原始 JSON 应该位于 PostStream
和 FormParams
应该为空。
话虽如此,在您的 Indy 版本中,TIdHTTPServer
只是从 PostStream
读取原始字节并将每个字节零扩展为 FormParams
中的 16 位字符.要恢复原始字节,只需将每个 Char
截断为 8 位 Byte
。例如,您可以在 ToBytes()
单元中使用 Indy 的 IdGlobal
函数,指定 enc8Bit
/IndyTextEncoding_8Bit
作为字节编码。
JSON 最常作为 UTF-8 传输(在您的示例中就是这种情况),因此当您可以访问任何版本的原始字节时,请确保将 JSON 字节解析为 UTF-8。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。