CefSharp の ChromiumWebBrowser でリクエストに関する処理をカスタムする場合、 CefSharp.IRequestHandler インターフェイスを実装したクラスのインスタンスを ChromiumWebBrowser の RequestHandler プロパティにセットする必要があります。
例えば、リンクを開く直前に移動先のURLによって許可したり拒否したりしたい場合は、 IRequestHandler のメソッド OnBeforeBrowse を実装すれば良いのですが、 IRequestHandler には他にも多数のメソッドが含まれるため、目的のメソッドを実装するだけでなく他のメソッドについても少なくとも最低限のものを実装しなければなりません。
各メソッドを最低限どう書けばよいかについては公式のサンプルソースに含まれるコードに答えがあるわけですが、その「答え」が「なぜそれで良いのか」についてはよく分からなかったので、ソースを読みながら自分なりの「最低限の答え」を導き出してみました。
といっても読んだのは主に IRequestHandler インターフェイスのソースに書かれているコメントだけです。
答えの前にまずは各メソッドの簡単な説明を。
欲しいのは「最低限」ですので、メソッドが呼ばれるタイミングとメソッドの戻り値以外については特に触れません。
bool OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, bool isRedirect);
bool OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture);
bool OnCertificateError(IWebBrowser browserControl, IBrowser browser, CefErrorCode errorCode, string requestUrl, ISslInfo sslInfo, IRequestCallback callback);
void OnPluginCrashed(IWebBrowser browserControl, IBrowser browser, string pluginPath);
CefReturnValue OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback);
bool GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback);
void OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status);
bool OnQuotaRequest(IWebBrowser browserControl, IBrowser browser, string originUrl, Int64 newSize, IRequestCallback callback);
void OnResourceRedirect(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, ref string newUrl);
bool OnProtocolExecution(IWebBrowser browserControl, IBrowser browser, string url);
void OnRenderViewReady(IWebBrowser browserControl, IBrowser browser);
bool OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response);
IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response);
void OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength);
全部で14個あります(-_-;)
ただし今日現在、 GetResourceResponseFilter は最新のソースには含まれてますが、NuGetの最新v47.0.3にはまだ含まれていないため、次の実装例には含めていません。
true を返すことでキャンセルを表現するメソッドもあれば、 false を返すことでキャンセルを表現するメソッドもあり、非常に分かりづらい感があります。
ですがよく調べると、 bool を返すメソッドでは false がデフォルト値になるよう敢えて真偽値の意味を変えてるようです。
であれば、とにかく false を返しておけばデフォルトの動作になるわけですからある意味分かりやすいともいえます。
(私が設計するときに真似したいとは思わないけど)
それとメソッドの名前が返り値について説明するようなものになってないのもつらいです。
ですがこれも、「メソッドのインターフェイス」ではなく「イベントハンドラのインターフェイス」と考えれば理解できます。
(私が設計するときはイベントハンドラをインターフェイスで定義しようとは思わないけど)
以上を踏まえた「ぼくの考えた最弱の実装」です。
これだけでは何もしない意味のないクラスですが、リクエスト関連のカスタマイズを行うためのスタート地点となるクラスです。
using CefSharp; namespace MyCefSharpTest { class MyRequestHandler : IRequestHandler { bool IRequestHandler.OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, bool isRedirect) { return false; } bool IRequestHandler.OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture) { return false; } bool IRequestHandler.OnCertificateError(IWebBrowser browserControl, IBrowser browser, CefErrorCode errorCode, string requestUrl, ISslInfo sslInfo, IRequestCallback callback) { return false; } void IRequestHandler.OnPluginCrashed(IWebBrowser browserControl, IBrowser browser, string pluginPath) { } CefReturnValue IRequestHandler.OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback) { return CefReturnValue.Continue; } bool IRequestHandler.GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback) { callback.Dispose(); return false; } void IRequestHandler.OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status) { } bool IRequestHandler.OnQuotaRequest(IWebBrowser browserControl, IBrowser browser, string originUrl, long newSize, IRequestCallback callback) { return false; } void IRequestHandler.OnResourceRedirect(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, ref string newUrl) { } bool IRequestHandler.OnProtocolExecution(IWebBrowser browserControl, IBrowser browser, string url) { return false; } void IRequestHandler.OnRenderViewReady(IWebBrowser browserControl, IBrowser browser) { } bool IRequestHandler.OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response) { return false; } void IRequestHandler.OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength) { } } }
こうやってまとめて見ると、基本的に void なメソッドは空に、 bool なメソッドは false を返すように、 CefReturnValue なメソッドは CefReturnValue.Continue を返すようにしただけですね。
GetAuthCredentials だけは callback.Dispose(); の行が追加されてますが、これは公式のサンプルのソース中にそうするようにおすすめするとコメントが書かれていたためそうしてみました。
終わってみれば簡単な事ですが、最初は「これだけのメソッドどうやって実装するんだ…」と軽く途方に暮れました。
一つのメソッド(イベントハンドラ)をカスタムしたいだけなのに、多数のメソッドがひとつのインターフェイスにまとまってるがために全部実装しなければならないのは、どう実装するか分かった今でも面倒な感じがあります。
今回私は OnBeforeBrowse のカスタムを目的としていましたが、他のテクノロジであれば同じようなイベントがブラウザに用意されているため、簡単にカスタムできるんですよね。
ということで IRequestHandler を実装しようとしたらメソッドが多すぎて途方に暮れた方は是非参考にしてみてください。(あまり居ないかな?w)
テクノロジ | ブラウザクラス | イベント |
Windows Forms | System.Windows.Forms.WebBrowser | Navigating |
UWP | Windows.UI.Xaml.Controls.WebView | NavigationStarting |
Geckofx | Gecko.GeckoWebBrowser | Navigating |
最近のコメント
名前
しゅごい
Jane Doe
FYI Avoid Annoying Unexpe…
Jane Doe
ご存じとは思いますが、whileには、”~の間”と…
peta_okechan
針金みたいなパーツを引っ張ると外れます。 他の方の…
虎徹ファン交換
虎徹の標準ファンを外す際に、どのようにして外されま…
花粉症対策2019 – 日曜研究室
[…] 花粉症対策についてはこれまで次の記事を書いてきました。https://…
花粉症対策2019 – 日曜研究室
[…] 花粉症対策についてはこれまで次の記事を書いてきました。https://…
花粉症対策2019 – 日曜研究室
[…] 花粉症対策についてはこれまで次の記事を書いてきました。https://…
花粉症対策2019 – 日曜研究室
[…] 花粉症対策についてはこれまで次の記事を書いてきました。https://…
花粉症対策2019 – 日曜研究室
[…] 花粉症対策についてはこれまで次の記事を書いてきました。https://…