pywebview icon indicating copy to clipboard operation
pywebview copied to clipboard

Start clean instance of webview

Open bvukotic opened this issue 4 years ago • 13 comments

Specification

  • pywebview version: 3.2
  • platform / version: Any

Description

It would be useful to start "clean" instance of pywebview (like incognito mode). Currently, cookies are remembered somewhere in the web engine, so each time I start webview session is not clean, some logins are remembered, etc... It would be nice to have something like

webview.start(clean=True)

JavaFX WebView starts clean every time (by default)

bvukotic avatar May 26 '20 15:05 bvukotic

Good suggestion. Clean state could be set default.

r0x0r avatar May 26 '20 20:05 r0x0r

API specs webview.start(clean_session=True) (enabled by default)

Links to implementations

Cocoa: https://stackoverflow.com/questions/42994553/creating-a-non-tracking-in-app-web-browser

GTK: https://webkitgtk.org/reference/webkit2gtk/unstable/WebKitCookieManager.html https://stackoverflow.com/questions/12220373/webkit-is-it-possible-to-store-cookies-to-file-and-reuse-it-again/15800193

QT: https://doc.qt.io/qt-5/qml-qtwebengine-webengineprofile.html

CEF: https://magpcss.org/ceforum/apidocs3/projects/(default)/CefRequestContext.html

MSHTML: https://stackoverflow.com/questions/13793261/disable-cookie-read-write-in-webbrowser-c-sharp-application

EdgeHTML: ¯\_(ツ)_/¯ Cookies are shared only if launched in the same host process https://docs.microsoft.com/en-us/windows/communitytoolkit/controls/wpf-winforms/webview

r0x0r avatar Jun 05 '20 09:06 r0x0r

Can I do this in my python code? I am on windows 10, I guess I (we) use mshtml, can I call the code mentioned here https://stackoverflow.com/questions/13793261/disable-cookie-read-write-in-webbrowser-c-sharp-application

but form python?

bvukotic avatar Jun 18 '20 06:06 bvukotic

This can be implemented, but it might require C# code. WebBrowserInterop.dll acts like a bridge for things that cannot be implemented in Python.

r0x0r avatar Jun 18 '20 07:06 r0x0r

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

github-actions[bot] avatar Aug 26 '20 01:08 github-actions[bot]

This would be a great addition to webview

analogaio avatar Oct 18 '20 00:10 analogaio

@Ksengine if you want to help, this issue would be a great choice.

r0x0r avatar Nov 20 '20 22:11 r0x0r

I can do qt and gtk.

Ksengine avatar Nov 21 '20 00:11 Ksengine

In my experience, the gtk webview doesn't store cookies [edit: by default]. I opened #687 to not save cookies in qt webengine.

obfusk avatar Jan 18 '21 12:01 obfusk

Example: how can you store and apply cookie jar to gtk webkit

from gi.repository import Gtk, WebKit, Soup
cookiejar = Soup.CookieJarText.new("<Your cookie path>", False)
cookiejar.set_accept_policy(Soup.CookieJarAcceptPolicy.ALWAYS)
session = WebKit.get_default_session()
session.add_feature(cookiejar)

Ksengine avatar Jan 19 '21 01:01 Ksengine

@obfusk 's PR merged into the incognito-mode branch.

r0x0r avatar Mar 08 '21 08:03 r0x0r

https://github.com/cztomczak/cefpython/blob/v66.0/examples/snippets/network_cookies.py

"""
Implement RequestHandler.CanGetCookies and CanSetCookie
to block or allow cookies over network requests.
"""

from cefpython3 import cefpython as cef


def main():
    cef.Initialize()
    browser = cef.CreateBrowserSync(
        url="http://www.html-kit.com/tools/cookietester/",
        window_title="Network cookies")
    browser.SetClientHandler(RequestHandler())
    cef.MessageLoop()
    del browser
    cef.Shutdown()


class RequestHandler(object):
    def __init__(self):
        self.getcount = 0
        self.setcount = 0

    def CanGetCookies(self, frame, request, **_):
        # There are multiple iframes on that website, let's log
        # cookies only for the main frame.
        if frame.IsMain():
            self.getcount += 1
            print("-- CanGetCookies #"+str(self.getcount))
            print("url="+request.GetUrl()[0:80])
            print("")
        # Return True to allow reading cookies or False to block
        return True

    def CanSetCookie(self, frame, request, cookie, **_):
        # There are multiple iframes on that website, let's log
        # cookies only for the main frame.
        if frame.IsMain():
            self.setcount += 1
            print("-- CanSetCookie @"+str(self.setcount))
            print("url="+request.GetUrl()[0:80])
            print("Name="+cookie.GetName())
            print("Value="+cookie.GetValue())
            print("")
        # Return True to allow setting cookie or False to block
        return True


if __name__ == '__main__':
    main()

Ksengine avatar Apr 01 '21 05:04 Ksengine

I have finally implemented this. EdgeChromium, CEF, GTK, QT and Cocoa are supported. PR here https://github.com/r0x0r/pywebview/pull/869

Incognito is now private_mode and is enabled by default. Implementation for each platform is rather hairy, but private mode works more reliably than non-private mode. Notable open issues are

  1. Built-in HTTP server starts on a random port by default. In order to support persistent local storage, a fixed port must be used. This PR introduces a default http server port 42001, which is used when private_mode=False and no custom http port is supplied
  2. Cocoa's nonPersistentMode does not work as expected, namely it preserves cookies over sessions. I have spent a fair time investigating this and found out that cookies come from NSHTTPCookieStorage in persistent mode. Why is it like this is beyond me. As a workaround all the storage is manually deleted in private_mode before launching webview. A drawback of this solution is that it deletes data for non-private sessions as well.

r0x0r avatar Mar 11 '22 07:03 r0x0r