加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – POST响应的TIdHTTP字符编码

发布时间:2020-12-15 04:20:04 所属栏目:大数据 来源:网络整理
导读:采取以下情况: procedure Test;var Response : String;begin Response := IdHttp.Post(MyUrL,AStream); DoSomethingWith(Response);end; 现在,web服务器以UTF-8返回数据. 假设它返回一些包含字符é的UTF-8 XML. 如果我使用变量Response它不包含这个字符,但
采取以下情况:
procedure Test;

var
 Response : String;

begin
 Response := IdHttp.Post(MyUrL,AStream);
 DoSomethingWith(Response);
end;

现在,web服务器以UTF-8返回数据.
假设它返回一些包含字符é的UTF-8 XML.
如果我使用变量Response它不包含这个字符,但它是UTF-8变种(#C3#A9),所以Indy没有解码?

现在我知道如何解决这个问题:

procedure Test;

var
 Response : String;

begin
 Response := UTF8ToString(IdHttp.Post(MyUrL,AStream));
 DoSomethingWith(Response);
end;

这个解决方案的一个警告:Delphi引发警告W1058(隐含的字符串转换,潜在的数据丢失从’string’到’RawByteString’)

我的问题:这是处理这个问题的正确方法,还是我可以指示TIdHTTP为我转换为UnicodeString?

解决方法

如果您使用的是Indy 10的最新版本,那么返回String的TIdHTTP.Post()的重载版本会将数据解码为Unicode,但用于解码的实际字符集取决于哪种媒体类型HTTP Content-Type响应头指定:

>如果媒体类型是application / xml,application / xml-external-parsed-entity,application / xml-dtd,或者不是text / …类型但以xml结尾,那么编码中指定的charset使用XML的prolog属性.如果未指定charset,则使用UTF-8.
>否则,如果Content-Type响应头指定了charset,则使用它.
>否则,如果媒体类型是text / …类型,则:

一个.如果媒体类型是text / xml,text / xml-external-parsed-entity,或以xml结尾,则使用us-ascii.

湾否则使用ISO-8859-1.
>否则,使用Indy的默认编码(默认为ASCII).

如果没有看到实际的HTTP Content-Type标头,很难知道您的情况属于哪种情况.听起来它落入#2或#3b,如果正在使用ISO-8859-1或类似的字符集,它将解释按原样返回的UTF-8字节值.

UTF8ToString()期望UTF-8编码的RawByteString作为输入,但您将传递UTF-16编码的UnicodeString.在这种情况下,RTL将执行UTF16-> Ansi转换,使用默认的Ansi字符集进行转换.这就是您收到编译器警告的原因,因为这样的转换可能会丢失数据.

XML实际上是一种二进制数据格式,受charset编码的限制. XML解析器需要知道XML的编码是什么,并能够相应地解析原始编码的字节.这就是为什么XML在XML prolog中具有明确的编码属性.但是,当TIdHTTP将XML作为字符串下载时,虽然它会自动将其解码为Unicode,但它还没有相应地更新XML的序言.

真正的解决方案是首先不要将XML作为String下载.将其作为TStream下载(TMemoryStream是比TStringStream更好的选择),因此您的XML解析器可以访问原始字节,原始字符集声明等.例如,您可以将TStream传递给TXMLDocument.LoadFromStream()方法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读