2013-07-06 116 views
2

我已经写了一些功能,通过URL下载指定网页的源代码:德尔福。印及西里尔字母

function GetWebPage(const url: string): tStringList; 
var 
    idHttp: TidHttp; 
begin 
    Result := tStringList.Create; 
    idHttp := TidHttp.Create(nil); 

    // set params 
    idHttp.Request.UserAgent := 'Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)'; 
    idHttp.Request.AcceptLanguage := 'ru en'; 
    idHttp.Response.KeepAlive := True; 
    idHttp.HandleRedirects := True; 
    idHttp.ConnectTimeout := 5000; 
    idHttp.ReadTimeout := 5000; 

    try 
    try 
     Result.values['responce'] := idHttp.Get(url); 
    except 
     Result.values['responce'] := ''; 
    end; 

    finally 
    Result.values['code'] := IntToStr(idHttp.ResponseCode); 
    FreeAndNil(idHttp); 
    end; 

I'ts英语URL不会忽略完美的工作,当我指定像президент.рф,iside一个网址印地那URL转变为?????????.?? - (HTTP分析仪的屏幕截图)

enter image description here

我发现这个解决我的问题:

idHttp.IOHandler.DefStringEncoding := TEncoding.Ansi; 
// also tried - TEncoding.Unicode, TEncoding.UTF8 

但它不工作 - 当我尝试打电话给我的功能,我得到错误:

enter image description here

所以,我怎么能强迫其功能与西里尔不会忽略工作?

谢谢。

+0

哇,真正的历史用户代理...但无论如何,您使用的是哪个版本的Delphi?你可以在你的问题中加入适当的标签吗? – TLama

+0

我正在使用Delphi XE3 :) –

+1

访问冲突意味着您正在访问无效内存。你在调试器内部运行,所以让它告诉你到底什么代码失败了。 –

回答

7

URL只能包含ASCII字符。在将其传递到TIdHTTP之前,您需要预先格式化URL以编码非ASCII字符。您可以使用TIdURI.URLEncode()方法为目的,例如:

Result.values['responce'] := idHttp.Get(TIdURI.URLEncode(url)); 

GetWebPage('http://президент.рф'); 

UTF-8通常用于URL编码,所以它是由TIdURL使用的默认编码,但不是所有的服务器使用UTF-8,所以如果你需要使用不同的编码,那么TIdURI.URLEncode()有一个可选的AByteEncoding参数用于此目的。

即便如此,国际资源使用IRIs而不是URL更好,但Indy本身不支持IRI(将在Indy 11中实现)。

+0

那不行... –

+1

以什么方式?你需要更具体。 HTTP分析器中的输出是否完全改变?如果不是,那么URL的主机名可能需要被IDN编码。 Indy在IdIDN.pas单元中有一个'IDNToPunnyCode()'函数。另外,我建议你通过一个实际的浏览器运行原始URL,并根据HTTP分析器了解它是如何被编码的,然后在Indy中复制它。 –

+0

是的,问题在域中,它需要被转换。函数'IDNToPunnyCode()'不工作,但我发现它的另一个功能。所以,只需要一个'TIdURI.URLEncode()'来编码url路径和参数。无论如何 - 感谢sugeestion。 :) –