経緯
前回の続きです。
今回は具体的なWebBrowserとの比較として、以下の機能の実装方法について検証します。
- UserAgentの設定
- ページ遷移のハンドリング
- Cookieの操作
UserAgentの設定
WebBrowserの場合
urlmon.dll
のUrlMkSetSessionOption
を利用すると実現できます→参考
難しいことはないんですがアンマネージドなコードを触るのがちょっともやっとします。
Cefの場合
CefSharp.Wpf.ChromiumWebBrowser
のインスタンスを生成する前に、Cef.Initialize(cefSettings)
を呼び出すことでUserAgent等の設定を行うことができます。
この関数の引数であるCefSettings
は他にもいろいろ設定できる項目があるので後々検証します。
今回はUserAgentを設定したいだけなので、UIスレッドでUserAgentを指定したCefSettingsを使ってCefをInitializeするだけです。
public static void Init()
{
var cefSettings = new CefSettings
{
UserAgent = "CefSample",
};
Cef.Initialize(cefSettings);
}
ちゃんとUserAgentがCefSampleになってます。
ページ遷移のハンドリング
WebBrowserの場合
WebBrowser.Navigating
, WebBrowser.Navigated
イベントがあるので、それぞれ遷移前、遷移後の処理をハンドリングすることができます。
また、Navigatingのイベントハンドラに第二引数として渡されるNavigatingCancelEventArgs
のCancelプロパティをtrueにしておくことで、遷移をキャンセルさせることができます。
Cefの場合
ChromiumWebBrowser.FrameLoadStart
, ChromiumWebBrowser.FrameLoadEnd
イベントがあるので、それぞれ遷移開始、遷移後の処理をハンドリングすることができます。
ただ、このFrameLoadStartイベントでは遷移をキャンセルすることができず、リクエストの書き換えや遷移のキャンセルを制御するにはChromiumWebBrowser.RequestHandler
プロパティを実装する必要があります。
RequestHandlerは多機能なので別途検証を行います(今回は行いません)。
Browser = new ChromiumWebBrowser();
Browser.FrameLoadStart += (sender, e) =>
{
var uri = new Uri(e.Url);
if (uri.Host == "www.google.co.jp")
{
MessageBox.Show("www.google.co.jpのページに遷移します");
}
};
みたいなことができます。
Cookieの操作
実際にやりたかったのは"クッキーを削除する"ボタンの実装なので、それをどうやって実現できそうかを見ていきます。
WebBrowserの場合
Cookieをまとめて削除するような機能はなさそうです(あったら教えてください)。
一応アンマネージドなコードを触ってInternetSetOptionでいろいろやれば既存のCookieを無視したブラウザを立ち上げることは可能なのですが、
直接消すわけではないので"クッキーを削除する"とは違う挙動になってしまいます。(オプションを無効化して再起動すると前のCookieが残ってる)
WebBrowserにはDocumentプロパティが存在して、HTMLにjsを挿入することができるので、そのjsでそのドメインのCookieのExpireをいじることは可能なのですが、
すべてのページのCookieを削除することは難しそうです。
Cefの場合
Cookieを操作するためのCookieManagerクラスが用意されていて、Cef.GetGlobalCookieManager()
でCookieManagerを取得することができます。
CookieManagerには特定のUrlのCookieを消すためのDeleteCookiesが実装されているので、一つだけ消す場合であればそれを呼べばOKです。
複数のドメインのCookieを処理するためにはアプローチを少し変える必要があって、ICookieVisitorを実装したクラスを用意して、そのインスタンスをCookieManagerのVisitAllCookiesに渡す必要があります(VisitUrlCookiesってのもあったのでドメインごとに消すとかも簡単にできそう)。
またasyncに処理してくれるVisitAllCookiesAsyncというものもあって、こちらは返り値でCookieのListを返してくれるのですが、返ってきたところでどうやって消せばいいのかはよくわかりませんでした。
void ClearAllCookies()
{
var cookieManager = Cef.GetGlobalCookieManager();
cookieManager.VisitAllCookies(new CookieEater());
}
class CookieEater : ICookieVisitor
{
public void Dispose()
{
}
public bool Visit(Cookie cookie, int count, int total, ref bool deleteCookie)
{
deleteCookie = true;
return true;
}
}
まとめ
- CefのInitializeにCefSettingsを渡すといろいろできる(UserAgentとかCacheのパスとか)
- FrameLoadStartとFrameLoadEndでページのロード開始とページのロード完了のイベントが取れる
- リクエスト自体をいじりたいとかならRequestHandlerを実装する必要がある(また今度検証)
- CookieManagerとCookieVisitorを使ってCookieを簡単に操作できる
今回はここまでです。
次回はRequestHandlerあたりについて書こうと思います。