无法解码使用IdHttp响应内容(Failed to decode response content

2019-08-04 14:23发布

我用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

我调试的原始响应,发现内容gzip压缩。

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

我也试着下载一个压缩的jQuery脚本文件,其中只包含ASCII字符。 这一次,它的工作原理,这意味着要印库的问题。 如果我没有错,我应该关闭的问题。

Answer 1:

TIdHTTP处理的gzip压缩的你,如果你有一个TIdCompressorZLib分配到组件TIdHTTP.Compressor财产。 否则,您必须手动将其解压缩( TIdHTTP不会发送Accept-Encoding由默认标题,如果Compressor未分配属性)。

对于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(...));


Answer 2:

不要使用任何自动检测编码,它不能可靠地完成。 简单地认为,Content-Type头。

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

如果Content-Type头丢失或卧,那么你就需要检测编码。 虽然我不会用会误测UTF-8作为CP936的任何算法...



文章来源: Failed to decode response content using IdHttp