How to always load a fresh page in TWebBrowser?

Z80 picture Z80 · Feb 10, 2015 · Viewed 9.1k times · Source

I am trying to load a web page into TWebBrowser using Browser.Navigate(URL). However, the browser won't care that the page was updated online so as long I won't restart the program it won't show the new page.

A more concrete example: If I navigate to a web page that has an visitor counter (as image), the counter will increment. If I navigate away from that page and then I return (without using Back), the counter won't increment. In Firefox, it does increment.

This is what I tried and won't work:

const
  DLCTL_PRAGMA_NO_CACHE = $00004000;

procedure TBrowserFrm.LoadURL(URL: string);
var
  Flag: OleVariant;
begin
  Flag:=DLCTL_PRAGMA_NO_CACHE;
  Browser.Navigate(URL, Flag);
end; 


procedure TBrowserFrm.LoadURL(URL: string);
var
Flags: OleVariant;
begin
 Flags := 'navNoHistory, navNoReadFromCache, navNoWriteToCache';
 Browser.navigate2(URL, Flags);
end;

Any idea on how to make the TWebBrowser load the real page?

Answer

Remy Lebeau picture Remy Lebeau · Feb 10, 2015

In VCL, TWebBrowser is a wrapper for Internet Explorer, specifically the IWebBrowser2 interface.

DLCTL_PRAGMA_NO_CACHE is NOT a flag you can pass to Navigate2(). Read the documentation:

SHDocVw.TWebBrowser

TWebBrowser wraps the IWebBrowser2 interface from Microsoft's Shell Doc Object and Control Library (SHDOCVW.DLL) to allow you to create a customized Web browsing application or to add Internet, file and network browsing, document viewing, and data downloading capabilities to your applications.

IWebBrowser2::Navigate2 Method

Flags [in] A pointer to a VARIANT of type VT_I4 or VT_I2 that specifies a combination of the values defined by the BrowserNavConstants enumeration.

BrowserNavConstants Enumerated Type

typedef enum BrowserNavConstants {
    navOpenInNewWindow = 0x1,
    navNoHistory = 0x2,
    navNoReadFromCache = 0x4,
    navNoWriteToCache = 0x8,
    navAllowAutosearch = 0x10,
    navBrowserBar = 0x20,
    navHyperlink = 0x40,
    navEnforceRestricted = 0x80,
    navNewWindowsManaged = 0x0100,
    navUntrustedForDownload = 0x0200,
    navTrustedForActiveX = 0x0400,
    navOpenInNewTab = 0x0800,
    navOpenInBackgroundTab = 0x1000,
    navKeepWordWheelText = 0x2000,
    navVirtualTab = 0x4000,
    navBlockRedirectsXDomain = 0x8000,
    navOpenNewForegroundTab = 0x10000
} BrowserNavConstants;

As you can see, DLCTL_PRAGMA_NO_CACHE is not on that list. It is actually a flag you specify as an output value when implementing a handler for the browser's DISPID_AMBIENT_DLCONTROL property. Read the MSDN documentation:

WebBrowser Customization | Controlling Download and Execution

The WebBrowser Control gives you control over what it downloads, displays, and executes. To gain this control, you need to implement your host's IDispatch so it handles DISPID_AMBIENT_DLCONTROL. When the WebBrowser Control is instantiated, it will call your IDispatch::Invoke with this ID. Set pvarResult to a combination of following flags, using the bitwise OR operator, to indicate your preferences.
...
•DLCTL_RESYNCHRONIZE and DLCTL_PRAGMA_NO_CACHE: These flags cause cache refreshes. With DLCTL_RESYNCHRONIZE, the server will be asked for update status. Cached files will be used if the server indicates that the cached information is up-to-date. With DLCTL_PRAGMA_NO_CACHE, files will be re-downloaded from the server regardless of the update status of the files.
...

So you would have to implement a custom IDispatch object and hook it into IWebBrowser2 in order to use DLCTL_PRAGMA_NO_CACHE correctly.

Alternatively, you might consider switching to TEmbeddedWB, which handles the browser customization for you, and has a DownloadOptions property that accepts DLCTL... flags, including DLCTL_PRAGMA_NO_CACHE.