【问题标题】:Failed to decode response content using IdHttp使用 IdHttp 解码响应内容失败
【发布时间】:2012-12-24 04:47:02
【问题描述】:

我使用 TIdHttp 来获取网页内容。响应头指示内容编码为 utf8。我想将控制台中的内容打印为 CP936(简体中文),但实际内容不可读。

Result := TEncoding.Utf8.GetString(ResponseBuffer);

我在 python 中做同样的事情(使用 httplib2)没有任何问题。

def python_try():
    conn = httplib2.HttpConn()
    respose, content = conn.get(...)
    print content.decode('utf8') # readable in console

更新 1

我调试了原始响应,发现内容被压缩了。

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Content-Encoding: gzip
Vary: Accept-Encoding
Date: Mon, 24 Dec 2012 15:27:44 GMT
Connection: Keep-Alive

我尝试将 IdCompressorZLib 实例分配给 IdHttp 实例。不幸的是,应用程序在解压缩 gzip 内容时会崩溃。测试地址为“http\://www.baidu.com”(编码=gb2312)。


更新 2

我还尝试下载一个 gzip 压缩的 jquery 脚本文件,它只包含 ascii 字符。这次成功了,这意味着是Indy库的问题。如果我没记错的话,我应该关闭这个问题。

【问题讨论】:

  • 缓冲区不会“检测”事物;他们只保存数据。检测的真正目的是什么?您期望收到什么代码页或编码? UTF-8 或 936 是否正确?
  • 你说的失败是什么意思?第一个变体应该是您需要的,但它转换为 UTF-16LE,而不是直接转换为您的代码页。最后一个变种已经到了那里,但是转换成很多了吗?我猜你只需要Cp936Encoding.GetString(TEncoding.Utf8.GetString(ResponseBuffer));
  • python 代码显示变体 1 是正确的,如果变体 1 显示不正确,那么这只是 display 的问题,而不是代码

标签: delphi encoding indy idhttp


【解决方案1】:

TIdHTTP 为您处理 gzip 解压缩,如果您有一个分配给 TIdHTTP.Compressor 属性的 TIdCompressorZLib 组件。否则,您将不得不手动解压(如果未分配 Compressor 属性,TIdHTTP 默认不会发送 Accept-Encoding 标头)。

至于 UTF-8 编码,TIdHTTP 也会为您处理,如果您调用的重载版本的 TIdHTTP.Get()TIdHTTP.Post() 方法返回 String 值而不是TStream 对象。它将为您将 UTF-8 解码为 UTF-16。要将其转换为 CP936,您可以让 RTL 为您进行转换:

type
  Cp936String = type AnsiString(936);
var
  S: Cp936String;
begin
  S := Cp936String(IdHTTP1.Get(...));

【讨论】:

  • 当我设置压缩器时,下载过程会崩溃。在要解码的内容期间会发生访问冲突。
  • 您使用的是哪个版本的 Indy?完整的错误信息是什么?
  • '0x00000038 处的访问冲突:读取地址 0x00000038'。在 IdZLib.pas(368):“如果 LocalTryStreamType(Result) 则开始”。我使用的 indy 来自 delphi xe2。
  • 我以前没有遇到过那个 AV。你能提供你下载的实际网址吗?
  • 您可以简单地尝试 IdHttp1.Get('http\://www.baidu.com') 和 IdCompressorZLib1 来重现崩溃。
【解决方案2】:

不要使用任何自动检测编码,它不能可靠地完成。只需相信 Content-Type 标头即可。

Result := TEncoding.Utf8.GetString(ResponseBuffer);

如果 Content-Type 标头丢失或存在错误,则需要检测编码。虽然我不会使用任何将 UTF-8 误检测为 CP936 的算法...

【讨论】:

  • 由于python代码工作,我不确定是TIdHttp返回错误的内容还是只是编码转换有问题。
  • @stanleyxu2005 它与您显示输出的方式有关......只需将其保存到文件或其他东西中
猜你喜欢
  • 2017-02-27
  • 2011-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-23
  • 1970-01-01
  • 1970-01-01
  • 2013-09-04
相关资源
最近更新 更多