Подписка

добавить на Яндекс

Наши проекты

Delphi+Google

Google API

Google API в Delphi - проект с открытым исходным кодом.

Chrono

Chrono

Хронометр - программа для ведения списка задач.

ODFProc

ODFProc

ODFProc - работа с документами OpenOffice в Lazarus и FreePascal.

Поддержка блога

А тут я коплю на лицензию Delphi XE на iPad =).
Сумма пожертвования не фиксирована.

Публикации

Год назад

Случайный пост

Последние

Сообщения форума

Комментарии

Социальные сети

Google

Facebook

Twitter

Опрос

Вы сейчас или в ближайшем обозримом будущем планируете разрабатывать кроссплатформенное приложение с использованием Firemonkey?



Loading ... Loading ...

Блоги и сообщества

Статьи по Delphi DelphiFeeds.ru - Все Delphi-блоги Рунета Сообщество умных людей VR-Online.RU Бесплатный журнал для программистов и всех, кто интересуется IT Статьи и уроки по Delphi Новостной блог о высоких технологиях
Система Orphus
Опубликовал Vlad 8 сентября 2009 в 14:41.
Категории: Delphi в Web.


Буквально на днях, разрабатывая небольшой компонент по работе с web-страничками столкнулся с проблемой - функция InternetCrackURL всё время выдавала false,  несмотря на то, что выполняла свое назначение - разбор URL на составляющие части.

Если Вы столкнулись с тем же, т.е. GetLastError все время выдает номера 87, 12006, 122 и пр., то эта статья поможет Вам от этих ошибок избавиться.

Например, если вспомнить тему про Captcha, то там вроде бы все работало "на ура", а вот такой код Delphi:

if InternetCrackUrl(PChar(aURL), Length(aURL), 0, aURLC) then
  begin
    FDomain:=aURLC.lpszHostName;
    Delete(FDomain,pos(aURLC.lpszUrlPath,aURLC.lpszHostName),length(aURLC.lpszUrlPath));
    if (Length(FURL)=0)or(pos(FDomain,FURL)=0) then
      SetURL(FDomain)
  end
else
  MessageBox(0, PChar('Ошибка WinInet #'+IntToStr(GetLastError)),'Ошибка', MB_OK);

всё время выдавал ошибки. Причем если сравнить два фрагмента (представленный выше и из темы про Captcha), то Вы можете убедиться, что различий практически нет. А ошибки есть. Вот я и решил немного разобраться и довести-таки работу с этой функцией до ума.

Итак, обратимся вначале к первоисточнику, посмотрим, что говорит про функцию MSDN:

InternetCrackURL разделяет URL на составные части

...

Возвращает TRUE в случае успеха. Чтобы получить дополнительную информацию об ошибке, вызовите GetLastError.

Параметр lpszUrl содержит указатель на строку, содержащую канонический URL для разборки

Параметр dwFlags может быть двух видов: ICU_DECODE и ICU_ESCAPE

...

Собственно ничего нового, делаем всё вроде бы правильно, а на выходе получаем ошибки с кодами: 87, 12006 и пр. В общем всё, кроме положительного результата.

Единственное, что остается делать - это разобраться, чем отличается канонический URL от неканонического? Хотя зачем лишний раз ломать голову, если есть функция InternetCanonicalizeUrl. Смотрим её описание:

Каноникализирует URL, преобразовывая небезопасные символы и пробелы в управляющие последовательности.

Воспользоваться функцией можно следующим образом:

var lencurl: cardinal;
    aURL: string;
begin
  lencurl:=INTERNET_MAX_URL_LENGTH;
  SetLength(aURL, lencurl);
  InternetCanonicalizeUrl(PChar(cURL),PChar(aURL),lencurl,ICU_BROWSER_MODE);
end;

где переменная cURL - это URL, который надо каноникализировать, а на выходе получим необходимый нам URL в переменной aURL. Для более подробного изучения параметров этой функции можете почитать справку MSDN, а нам и этого фрагмента будет достаточно.

Теперь дополняем нашу функцию по разбору URL следующим образом:

....
lencurl:=INTERNET_MAX_URL_LENGTH;
SetLength(aURL, lencurl);
InternetCanonicalizeUrl(PChar(cURL),PChar(aURL),lencurl,ICU_BROWSER_MODE);
if InternetCrackUrl(PChar(aURL), Length(aURL), 0, aURLC) then
  begin
    FDomain:=aURLC.lpszHostName;
    Delete(FDomain,pos(aURLC.lpszUrlPath,aURLC.lpszHostName),length(aURLC.lpszUrlPath));
    if (Length(FURL)=0)or(pos(FDomain,FURL)=0) then
      SetURL(FDomain)
  end
else
  MessageBox(0, PChar('Ошибка WinInet #'+IntToStr(GetLastError)),'Ошибка', MB_OK);
....

т.е. передаем в InternetCrackURL явно каноникализированный URL и всё - функция работает как надо, без всяких непредвиденных ошибок.  Я не знаю специально ли или нет разработчики Microsoft не включили в тело функции InternetCrackURL проверку на каноничность URL, но как бы там ни было, без связки с InternetCanonicalizeUrl она работает некорректно, даже если вы будете ей "скармливать" адреса типа http://www.webdelphi.ru (без всяких пробелов и не безопасных символов).
Ну, и конечно, не забывайте проверять свой URL на наличие подстроки "http://" либо явно указывайте схему URL'а.
Раз уж речь зашла о работе в Интернет, то, думаю, что для желающих открыть свой бизнес в Интернет будет полезно узнать где делается сайт визитка под ключ - лицо Вашего Интернет-проекта.

Мой блог находят по следующим фразам

Понравилась статья? Тогда:
Делись! Загружай! Плюсуй!
   Отправить PDF на   
Читай ещё статьи на WebDelphi.ru

Комментарии (6)

WP_Cloudy
  • sbseo пишет:

    А нет ли какого юнита или компонента, для реализаций этих функций без привязки к WinIntet, уж больно это глючная библиотека.

  • Vlad пишет:

    Можно конечно и без WinInet, но по-моему глюков от этого не убавится (если таковые есть). Да, и в принципе, из WinInet всего 2 функции используются.

  • Alex - CyberMake пишет:

    Все гораздо проще, неужели никто не заклядывал внутрь синапса?
    Используйте просто библиотеку synautil.pas
    Функция ParseURL, напишите небольшую прослойку на нее, чтобы не вызывать каждый раз кучу параметров, а давать на функцию всего 2 парметра: URL и тип возвращаемого юрл (Host, Path, Para) и все готово.
    Выдает следующие параемтры: URL, Prot, User, Pass, Host, Port, Path, Para
    Причем парсит быстро и без багов и без WinIntet !

  • Vlad пишет:

    Alex – CyberMake, неужели вы не смотрели дальше этого поста? =) Synapse уже давным давно расписан вдоль и поперек в этом блоге, в том числе и модуль sunautil.pas. А случаи бывают разные — кто-то работает с Synapse, а кому-то WinInet подавай

  • Alex - CyberMake пишет:

    Vlad, я отвечал на этот вопрос:

    sbseo пишет:
    25 Сен 2009 в 3:59 дп

    А нет ли какого юнита или компонента, для реализаций этих функций без привязки к WinIntet, уж больно это глючная библиотека.

      Разве я на него не ответил? И зачем вы мне это пишите куда я смотрел или не смотрел и удаляете мои посты?

  • Vlad пишет:

    Alex – CyberMakeб всегда отвечаете на комментарии 2 (двух)-летней давности? И какие посты я удаляю?

Ваш ответ

Внимание: Все комментарии модерируются, и это может вызвать задержку их публикации. Отправлять комментарий заново не требуется.

Пожалуйста, заключайте исходный код в тэги [code][/code].
Если код большой, то воспользуйтесь Вставкой кода на отдельной странице и оставьте в комментарии ссылку на исходник

   


Регистрация фирм с лицензиями. Регистрация фирм новый форум.