无法使用IdHttp解码响应内容

时间:2012-12-24 04:47:02

标签: delphi encoding indy idhttp

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

我还尝试下载一个gzip压缩的jquery脚本文件,该文件只包含ascii字符。这次它有效,这意味着Indy库的问题。如果我没有错,我应该结束这个问题。

2 个答案:

答案 0 :(得分:2)

如果您将TIdHTTP组件分配给TIdCompressorZLib属性,

TIdHTTP.Compressor会为您处理gzip解压缩。否则,您必须手动解压缩(TIdHTTP默认情况下,如果未分配Accept-Encoding属性,则不会发送Compressor标头。

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

TStream

答案 1 :(得分:1)

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

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

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