FoxBase!
msgbartop
Блог Oracle разработчика
msgbarbottom
foxbase

24.04.2011 Как очистить Cookies в TWebBrowser

 Cookies TWebBrowser
Тема очистки Cookies на Delphi в TWebBrowser, который, как известно, является оболочкой для Internet Explorer, многократно пережевана в интернете на всевозможных форумах и блогах. В результате можно найти множество решений этой щекотливой проблемы, которые, однако, толком не работают или работают не так, как вы ожидаете. В результате на полном серьезе обсуждаются методы очистки Cookies в TWebBrowser методом пересоздания экземпляра объекта а также методом перезагрузки приложения целиком! Тихий ужас. Кто-то что-то знает, но недоговаривает, кто-то пытается что-то понять и так и хлопает ушами от недоумения, так как известные описанные приемы работают как то немножко не так и немножко требуют тупой перезагрузки приложения для того, чтобы очистить куки несчастного и всеми презираемого Internet Explorer. Попробуем прояснить суть вопроса.
Ниже я приведу код, который в основном и встречается в сети как работающий вариант очистки Cookies в TWebBrowser (однако в сети встречаются и неработающие варианты этого кода). Кто непосредственный автор этого кода, неизвестно. 

uses WinInet;
procedure ClearCookies;
var
  lpEntryInfo: PInternetCacheEntryInfo;
  hCacheDir: LongWord;
  dwEntrySize: LongWord;
begin
  dwEntrySize := 0;
  FindFirstUrlCacheEntry(nil, TInternetCacheEntryInfo(nil^), dwEntrySize);
  GetMem(lpEntryInfo, dwEntrySize);
  if dwEntrySize > 0 then lpEntryInfo^.dwStructSize := dwEntrySize;
  hCacheDir := FindFirstUrlCacheEntry(nil, lpEntryInfo^, dwEntrySize);
  if hCacheDir <> 0 then
  begin
    repeat
      DeleteUrlCacheEntry(lpEntryInfo^.lpszSourceUrlName);
      FreeMem(lpEntryInfo, dwEntrySize);
      dwEntrySize := 0;
      FindNextUrlCacheEntry(hCacheDir, TInternetCacheEntryInfo(nil^), dwEntrySize);
      GetMem(lpEntryInfo, dwEntrySize);
      if dwEntrySize > 0 then lpEntryInfo^.dwStructSize := dwEntrySize;
    until not FindNextUrlCacheEntry(hCacheDir, lpEntryInfo^, dwEntrySize);
  end;
  FreeMem(lpEntryInfo, dwEntrySize);
  FindCloseUrlCache(hCacheDir);
end;
Этот код работает следующим образом. Анализируются все текущие куки TWebBrowser и все, которые найдены, удаляются с диска в каталоге: 

c:\Documents and Settings\YourUserName\Cookies
Действительно, так и происходит. Файлы с куками из этого каталога удаляются (не все, только соответствующие текущей сессии TWebBrowser). Это можно наблюдать прямо в проводнике Windows. Однако если попытаться выполнить повторную навигацию на тот же сайт, с которым вы работали до очистки куков и на котором вы были залогинены, то вы опять будете залогинены прежним логином. В итоге куки никуда не пропали. Мало того, множество горе-программеров вводит в полную прострацию то, что после удаления (Free или Destroy) экземпляра компонента TWebBrowser и его повторного создания, куки опять откуда то вылезают, как птица Феникс, и опять появляются в виде файлов на диске. 
Вот такие вот дела, при этом в сети даже приводятся какие-то дикие способы очистки куков, которые работают с перезагрузкой программы или без таковой, с такой-то версией Internet Explorer-а или с другой. В общем, бред полный, не буду приводить ссылки на такие работы. 
Попробую прояснить ситуацию. Дело в том, что простое тупое физическое удаление файлов Cookies с диска это только удаление файлов. Internet Explorer-у на это с большой колокольни. Вызывает удивление, что при удалении экземпляра объекта TWebBrowser и его повторном создании куки все равно где-то там сидят? Спасает только перезагрузка приложения целиком? Чудеса, да и только. А дело в том, что TWebBrowser это всего лишь оболочка для IE. И удаление/создание оболочки неспособно изменить состояние самого IE. Internet Explorer-у необходимо сообщить, что сессия завершена. Вот тогда он и завершит сессию работы с этим же сайтом и при начале новой сессии не найдет куков для этого сайта в заветном каталоге на диске вашего ПК, если вы их предварительно удалите. Иначе IE найдет куки в незавершенной сессии, которая хранится в памяти IE, а не на диске. Понимаете?
Вот еще одна функция в дополнение к предыдущей:

uses WinInet;
procedure EndBrowserSession;
  InternetSetOption(nil, INTERNET_OPTION_END_BROWSER_SESSION, nil, 0);
end;
Вот теперь мы можем делать с куками TWebBrowser все, что нам необходимо. Если ситуация, например, требует работать с одним и тем же сайтом подряд с разными логинами, то перед началом новой сессии TWebBrowser сначала очистите куки при помощи функции ClearCookies, затем прервите предыдущую сессию при помощи EndBrowserSession. Или наоборот. Или просто вызывайте EndBrowserSession, если вам не требуется физическое удаление куков с диска.  При этом вам не потребуется ничего перегружать и пересоздавать. 

www.foxbase.ru


Смотрите также:



Оставьте свой комментарий

Вы должны быть авторизированны, чтобы оставить комментарий.