Welcome Guest Search | Active Topics | Sign In | Register

Incognito mode to prevent localstorage sharing in HtmlToPdf.Convert method of EO.PDF Options
Michiel Reuser
Posted: Wednesday, June 25, 2025 3:17:12 AM
Rank: Newbie
Groups: Member

Joined: 1/23/2019
Posts: 3
We have a .NET webservice where we use HtmlToPdf.Convert method of EO.PDF to convert a web page into a PDF. The URL of the web page is always the same but we pass different querystring value each time. so the web page loads different form in each run. However, it seems that local-storage and session-storage values are being retained between consecutive PDF conversions. We are looking to run each PDF conversion in private or incognito mode, so that local-storage and session-storage are not shared across multiple runs.

We have already tried a few things:
1.We tried to set a new CacheFolder for each run but CacheFolder is a static property and cannot be changed until we restart the webservice.
2. We tried to force delete the CacheFolder after reach run, but it failed with error that the files are in use.
2. We tried creating a new instance of EO.WebEngine.Engine for each run, but there is no way to assign the new engine to HtmlToPdf at runtime.
3. We tried HTMLtoPDFSession with using block, but still the local-storage and session-storage values did not get disposed before the next run.

How can we set incognito mode during PDF conversion, or can we achieve this by using some other approach? Please suggest.
eo_support
Posted: Thursday, June 26, 2025 10:40:08 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,383
Hi,

For performance reasons, internally EO.Pdf uses a pool of WebView objects for conversion. So it will always reuse WebViews. However it is possible for you to disable both localStorage and cache even if WebViews are reused.

To disable localStorage, you can use HtmlToPdfOptions.JSInitCode to explicitly override window.localStorage to a non-functioning one. For example:

Code: C#
HtmlToPdfOptions options = new HtmlToPdfOptions();

//This runs JSInitCode inside the WebView before a page is being loaded.
//The code here replaces the built-in window.localStorage interface with
//a non-functioning version where getItem always returns null and setItem
//does nothing
options.JSInitCode = @"
Object.defineProperty(window, 'localStorage', {
    configurable: false,
    enumerable: true,

    value: {
        getItem: function (sKey) { return null; },
        setItem: function (sKey, sValue) {}
    }
});";
using (HtmlToPdfSession session = HtmlToPdfSession.Create(options))
{
    //Perform the conversion
    session.LoadUrl(url);
    session.RenderAsPDF(result_pdf_file);
}


To disable cache, you can handle the internal WebView's BeforeRequestLoad event to explicitly add Cache-Control header entry to disable the cache. For example:

Code: C#
using (HtmlToPdfSession session = HtmlToPdfSession.Create(options))
{
    BeforeRequestLoadHandler handler = (sender, e) =>
    {
        e.Request.Headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
    };

    //Attach BeforeRequestLoad handler
    session.RunWebViewCallback(() =>
    {
        session.WebView.BeforeRequestLoad += handler;
    });

    //Perform conversion
    session.LoadUrl(url);
    session.RenderAsPDF(result_pdf_file);

    //Detach BeforeRequestLoad handler
    session.RunWebViewCallback(() =>
    {
        session.WebView.BeforeRequestLoad -= handler;
    });
}


Please let us know if this works for you.

Thanks!
Michiel Reuser
Posted: Friday, June 27, 2025 8:18:50 AM
Rank: Newbie
Groups: Member

Joined: 1/23/2019
Posts: 3
Hi,
Thank you for your response. We have to make use of localstorage, so we cannot fully disable it. Your suggestion inspired me to use a custom localstorage each time, as shared in code below. Do you see this as a feasible solution or can it have potential issues? Please advise.

Code: C#
HtmlToPdf.Options.JSInitCode = @" 
    Object.defineProperty(window, 'localStorage', {
    configurable: false,
    enumerable: true,
    value: (function() {
        const customStorage = {};
        return {
            getItem: function (sKey) {
                return Object.prototype.hasOwnProperty.call(customStorage, sKey) ? customStorage[sKey] : null;
            },
            setItem: function (sKey, sValue) {
                customStorage[sKey] = String(sValue);
            },
            removeItem: function (sKey) {
                delete customStorage[sKey];
            },
            clear: function () {
                for (const key in customStorage) {
                    if (Object.prototype.hasOwnProperty.call(customStorage, key)) {
                        delete customStorage[key];
                    }
                }
            },
            get length() {
                return Object.keys(customStorage).length;
            },
            key: function(index) {
                return Object.keys(customStorage)[index] || null;
            }
        };
    })()
});";
eo_support
Posted: Friday, June 27, 2025 9:27:31 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,383
Yes. This will work as long as you are not planing to share localStorage between pages --- including iframes.


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.