2013-07-06 1 views
2

Я пишу какую-то функцию, которая загружает исходный код из указанного веб-страницы по адресу:Delphi. Инди и кириллические буквы

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, когда я указать URL, как президент.рф, ИСИДЕ Инди, что URL преобразуется в ?????????.?? - (экранное изображение HTTP Analyzer)

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. Вам необходимо предварительно форматировать URL-адрес для кодирования символов, отличных от ASCII, а затем передать его TIdHTTP. Вы можете использовать метод 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 имеет функцию IDNToPunnyCode() 'в модуле IdIDN.pas. Кроме того, я предлагаю вам запустить исходный URL-адрес через фактический веб-браузер и посмотреть, как он закодирован, согласно HTTP-анализу, а затем повторить его в Indy. –

+0

Да, проблема в доменах, она должна быть преобразована. Функция 'IDNToPunnyCode()' не работает, но я нашел для нее другую функцию. Таким образом, 'TIdURI.URLEncode()' требуется только для кодирования пути и параметров URL-адреса. Во всяком случае - спасибо за sugeestion. :) –