WebView

.NET Multi-platform App UI (.NET MAUI) WebView は、リモート Web ページ、ローカル HTML ファイル、HTML 文字列をアプリに表示します。 WebView を表示するコンテンツには、カスケード スタイル シート (CSS) と JavaScript のサポートが含まれています。 既定では、.NET MAUI プロジェクトには、WebView がリモート Web ページを表示するために必要なプラットフォームのアクセス許可が含まれています。

WebView は次の特性を定義します。

  • CookieContainer 型 の Cookies は、Cookie のコレクションのストレージを提供します。
  • bool 型の CanGoBack は、ユーザーが前のページに移動できるかどうかを示します。 これは、読み取り専用プロパティです。
  • bool 型の CanGoForward は、ユーザーが前方に移動できるかどうかを示します。 これは、読み取り専用プロパティです。
  • WebViewSource 型の Source は、WebView が表示される場所を表します。
  • CookieContainer 型 の Cookies は、Cookie のコレクションのストレージを提供します。
  • bool 型の CanGoBack は、ユーザーが前のページに移動できるかどうかを示します。 これは、読み取り専用プロパティです。
  • bool 型の CanGoForward は、ユーザーが前方に移動できるかどうかを示します。 これは、読み取り専用プロパティです。
  • WebViewSource 型の Source は、WebView が表示される場所を表します。
  • string 型の UserAgent は、ユーザー エージェントを表します。 既定値は、基になるプラットフォーム ブラウザーのユーザー エージェントか、判断できない場合は null です。

これらのプロパティは、BindableProperty オブジェクトが基になっています。つまり、これらは、データ バインディングの対象にすることができ、スタイルを設定できます。

Source プロパティは、UrlWebViewSource オブジェクトまたは HtmlWebViewSource オブジェクトに設定できます。これらのオブジェクトはどちらも WebViewSource から派生したものです。 UrlWebViewSource は URL で指定された Web ページの読み込みに使用され、HtmlWebViewSource オブジェクトはローカル HTML ファイルまたはローカル HTML の読み込みに使用されます。

WebView は、ページ ナビゲーションの開始時に発生する Navigating イベントと、ページ ナビゲーションの完了時に発生する Navigated イベントを定義します。 Navigating イベントに付随する WebNavigatingEventArgs オブジェクトは、ナビゲーションを取り消すために使用できる bool 型の Cancel プロパティを定義します。 Navigated イベントに付随する WebNavigatedEventArgs オブジェクトは、ナビゲーション結果を示す WebNavigationResult 型の Result プロパティを定義します。

重要

HorizontalStackLayoutStackLayout または VerticalStackLayout に含まれている場合、WebView には HeightRequest プロパティと WidthRequest プロパティを指定する必要があります。 これらのプロパティを指定しないと、WebView はレンダリングされません。

Web ページを表示する

リモート Web ページを表示するには、Source プロパティを、URI を指定する string に設定します。

<WebView Source="https://learn.microsoft.com/dotnet/maui" />

同等の C# コードを次に示します。

WebView webvView = new WebView
{
    Source = "https://learn.microsoft.com/dotnet/maui"
};

URI は、指定されたプロトコルで完全に形成されている必要があります。

Note

Source プロパティが WebViewSource 型であるにもかかわらず、プロパティは文字列ベースの URI に設定できます。 これは、.NET MAUI には、型コンバーターと、文字列ベースの URI を UrlWebViewSource オブジェクトに変換する暗黙的な変換演算子が含まれているためです。

iOS と Mac Catalyst でアプリケーション トランスポート セキュリティを構成する

バージョン 9 以降、iOS ではアプリとセキュリティで保護されたサーバーとの通信のみが許可されます。 アプリは、セキュリティで保護されていないサーバーとの通信を有効にすることを選択する必要があります。

次の Info.plist 構成は、特定のドメインを有効にして Apple Transport Security (ATS) 要件をバイパスする方法を示しています。

	<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSExceptionDomains</key>
		<dict>
			<key>mydomain.com</key>
			<dict>
				<key>NSIncludesSubdomains</key>
				<true/>
				<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
				<true/>
				<key>NSTemporaryExceptionMinimumTLSVersion</key>
				<string>TLSv1.1</string>
			</dict>
		</dict>
	</dict>

ATS をバイパスするには、特定のドメインのみを有効にすることをお勧めします。信頼されていないドメインのセキュリティを強化しながら、信頼済みサイトを使用できます。

次の Info.plist 構成は、アプリの ATS を無効にする方法を示しています。

	<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSAllowsArbitraryLoads</key>
		<true/>
	</dict>

重要

アプリで安全でない Web サイトへの接続が必要な場合は、NSAllowsArbitraryLoads キーを使用して ATS を完全にオフにするのではなく、常に NSExceptionDomains キーを使用してドメインを例外として入力する必要があります。

ローカル HTML を表示する

インライン HTML を表示するには、次のように Source プロパティを HtmlWebViewSource オブジェクトに設定します。

<WebView>
    <WebView.Source>
        <HtmlWebViewSource Html="&lt;HTML&gt;&lt;BODY&gt;&lt;H1&gt;.NET MAUI&lt;/H1&gt;&lt;P&gt;Welcome to WebView.&lt;/P&gt;&lt;/BODY&gt;&lt;HTML&gt;" />
    </WebView.Source>
</WebView>

XAML では、< 記号や > 記号がエスケープされ、HTML 文字列が読めなくなる可能性があります。 したがって、読みやすくするために、HTML を CDATA セクションにインライン化できます。

<WebView>
    <WebView.Source>
        <HtmlWebViewSource>
            <HtmlWebViewSource.Html>
                <![CDATA[
                <HTML>
                <BODY>
                <H1>.NET MAUI</H1>
                <P>Welcome to WebView.</P>
                </BODY>
                </HTML>
                ]]>
            </HtmlWebViewSource.Html>
        </HtmlWebViewSource>
    </WebView.Source>
</WebView>

同等の C# コードを次に示します。

WebView webView = new WebView
{
    Source = new HtmlWebViewSource
    {
        Html = @"<HTML><BODY><H1>.NET MAUI</H1><P>Welcome to WebView.</P></BODY></HTML>"
    }
};

ローカル HTML ファイルを表示する

ローカル HTML ファイルを表示するには、アプリ プロジェクトの Resources\Raw フォルダーにファイルを追加し、そのビルド アクションを MauiAsset に設定します。 その後、Source プロパティの値として設定されている HtmlWebViewSource オブジェクトで定義されているインライン HTML からファイルを読み込むことができます。

<WebView>
    <WebView.Source>
        <HtmlWebViewSource>
            <HtmlWebViewSource.Html>
                <![CDATA[
                <html>
                <head>
                </head>
                <body>
                <h1>.NET MAUI</h1>
                <p>The CSS and image are loaded from local files!</p>
                <p><a href="localfile.html">next page</a></p>
                </body>
                </html>                    
                ]]>
            </HtmlWebViewSource.Html>
        </HtmlWebViewSource>
    </WebView.Source>
</WebView>

ローカル HTML ファイルは、MauiAsset ビルド アクションを使用してアプリ プロジェクトにも追加されている場合、カスケード スタイル シート (CSS)、JavaScript、イメージを読み込むことができます。

生アセットの詳細については、「Raw assets」をご覧ください。

コンテンツを再読み込みする

WebView には、ソースを再読み込みするために呼び出すことができる Reload メソッドがあります。

WebView webView = new WebView();
...
webView.Reload();

Reload メソッドが呼び出されると、現在のコンテンツを再読み込みする要求が行われていることを示す ReloadRequested イベントが発生します。

ナビゲーションを実行する

WebView では、GoForwardGoBack メソッドによるプログラムのナビゲーションがサポートされています。 これらのメソッドは、WebView ページ スタック内のナビゲーションを有効にし、CanGoBack および CanGoForward プロパティの値を調べた後にのみ呼び出す必要があります。

WebView webView = new WebView();
...

// Go backwards, if allowed.
if (webView.CanGoBack)
{
    webView.GoBack();
}

// Go forwards, if allowed.
if (webView.CanGoForward)
{
    webView.GoForward();
}

プログラムによって開始されるか、ユーザーによって WebView でページ ナビゲーションが発生すると、次のイベントが発生します。

  • Navigating は、ページ ナビゲーションの開始時に発生します。 Navigating イベントに付随する WebNavigatingEventArgs オブジェクトは、ナビゲーションを取り消すために使用できる bool 型の Cancel プロパティを定義します。
  • Navigated は、ページ ナビゲーションが完了したときに発生します。 Navigated イベントに付随する WebNavigatedEventArgs オブジェクトは、ナビゲーション結果を示す WebNavigationResult 型の Result プロパティを定義します。

Android でのアクセス許可の処理

カメラやマイクなど、デバイスの録音ハードウェアへのアクセスを要求するページを参照する場合は、WebView コントロールによってアクセス許可が付与されている必要があります。 WebView コントロールでは、Android 上の Android.Webkit.WebChromeClient 型を使用してアクセス許可要求に対応します。 ただし、.NET MAUI によって提供される WebChromeClient 実装では、アクセス許可要求は無視されます。 アクセス許可要求を MauiWebChromeClient から継承して承認する新しい型を作成する必要があります。

重要

この方法を使用してアクセス許可要求を承認するように WebView をカスタマイズするには、Android API 26 以降が必要です。

Web ページから WebView コントロールへのアクセス許可要求は、.NET MAUI アプリからユーザーへのアクセス許可要求とは異なります。 .NET MAUI アプリのアクセス許可は、アプリ全体に対してユーザーによって要求され、承認されます。 WebView コントロールは、ハードウェアにアクセスするアプリの機能に依存します。 この概念を説明するために、デバイスのカメラへのアクセスを要求する Web ページを検討します。 要求が WebView コントロールによって承認されているにもかかわらず、.NET MAUI アプリがユーザーによるカメラへのアクセスの承認を得ていなかった場合でも、Web ページはカメラにアクセスできません。

次の手順では、カメラを使用するために WebView コントロールからのアクセス許可要求をインターセプトする方法を示します。 マイクを使用する場合は、カメラ関連のアクセス許可ではなくマイク関連のアクセス許可を使用する以外は、手順は似ています。

  1. まず、必要なアプリのアクセス許可を Android マニフェストに追加します。 Platforms/Android/AndroidManifest.xml ファイルを開き、manifest ノードに以下を追加します。

    <uses-permission android:name="android.permission.CAMERA" />
    
  2. WebView コントロールを含むページが読み込まれる場合など、アプリのある時点で、カメラへのアプリ アクセスを許可するアクセス許可をユーザーに要求します。

    private async Task RequestCameraPermission()
    {
        PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.Camera>();
    
        if (status != PermissionStatus.Granted)
            await Permissions.RequestAsync<Permissions.Camera>();
    }
    
  3. Platforms/Android フォルダーに次のクラスを追加し、プロジェクトの名前空間に合わせてルート名前空間を変更します。

    using Android.Webkit;
    using Microsoft.Maui.Handlers;
    using Microsoft.Maui.Platform;
    
    namespace MauiAppWebViewHandlers.Platforms.Android;
    
    internal class MyWebChromeClient: MauiWebChromeClient
    {
        public MyWebChromeClient(IWebViewHandler handler) : base(handler)
        {
    
        }
    
        public override void OnPermissionRequest(PermissionRequest request)
        {
            // Process each request
            foreach (var resource in request.GetResources())
            {
                // Check if the web page is requesting permission to the camera
                if (resource.Equals(PermissionRequest.ResourceVideoCapture, StringComparison.OrdinalIgnoreCase))
                {
                    // Get the status of the .NET MAUI app's access to the camera
                    PermissionStatus status = Permissions.CheckStatusAsync<Permissions.Camera>().Result;
    
                    // Deny the web page's request if the app's access to the camera is not "Granted"
                    if (status != PermissionStatus.Granted)
                        request.Deny();
                    else
                        request.Grant(request.GetResources());
    
                    return;
                }
            }
    
            base.OnPermissionRequest(request);
        }
    }
    

    前のスニペットでは、MyWebChromeClient クラスは MauiWebChromeClient を継承し、OnPermissionRequest メソッドをオーバーライドして Web ページの許可要求をインターセプトします。 各アクセス許可項目は、カメラを表す PermissionRequest.ResourceVideoCapture 文字列定数と一致するかどうかを確認するためにチェックされます。 カメラのアクセス許可が一致した場合、コードは、アプリにカメラの使用許可があるかどうかを確認します。 アクセス許可がある場合は、Web ページの要求が付与されます。

  4. Android の WebView コントロールで SetWebChromeClient メソッドを使用して、Chrome クライアントを MyWebChromeClient に設定します。 次の 2 つの項目は、Chrome クライアントを設定する方法を示しています。

    • .NET MAUI WebView コントロールの名前付き theWebViewControl を指定すると、プラットフォーム ビュー (Android コントロール) で Chrome クライアントを直接設定できます。

      ((IWebViewHandler)theWebViewControl.Handler).PlatformView.SetWebChromeClient(new MyWebChromeClient((IWebViewHandler)theWebViewControl.Handler));
      
    • また、ハンドラー プロパティ マッピングを使用して、すべての WebView コントロールに Chrome クライアントの使用を強制することもできます。 詳細については、「ハンドラー」をご覧ください。

      次のスニペットの CustomizeWebViewHandler メソッドは、MauiProgram.CreateMauiApp メソッド内など、アプリの起動時に呼び出す必要があります。

      private static void CustomizeWebViewHandler()
      {
      #if ANDROID26_0_OR_GREATER
          Microsoft.Maui.Handlers.WebViewHandler.Mapper.ModifyMapping(
              nameof(Android.Webkit.WebView.WebChromeClient),
              (handler, view, args) => handler.PlatformView.SetWebChromeClient(new MyWebChromeClient(handler)));
      #endif
      }
      

Cookie の設定

Cookie は、Web 要求と共に指定された URL に送信されるように、WebView に設定できます。 Cookie オブジェクトを CookieContainer に追加して Cookie を設定し、コンテナーをバインド可能なプロパティの WebView.Cookies 値として設定します。 次に例を示します。

using System.Net;

CookieContainer cookieContainer = new CookieContainer();
Uri uri = new Uri("https://learn.microsoft.com/dotnet/maui", UriKind.RelativeOrAbsolute);

Cookie cookie = new Cookie
{
    Name = "DotNetMAUICookie",
    Expires = DateTime.Now.AddDays(1),
    Value = "My cookie",
    Domain = uri.Host,
    Path = "/"
};
cookieContainer.Add(uri, cookie);
webView.Cookies = cookieContainer;
webView.Source = new UrlWebViewSource { Url = uri.ToString() };

この例では、1 つの CookieCookieContainer オブジェクトに追加し、WebView.Cookies プロパティの値として設定します。 WebView が指定した URL に Web 要求を送信すると、要求と共に Cookie が送信されます。

JavaScript を呼び出す

WebView は、C# から JavaScript 関数を呼び出して、呼び出し元の C# コードに結果を返すことができます。 次の例に示すように、この相互運用は EvaluateJavaScriptAsync メソッドで実現されます。

Entry numberEntry = new Entry { Text = "5" };
Label resultLabel = new Label();
WebView webView = new WebView();
...

int number = int.Parse(numberEntry.Text);
string result = await webView.EvaluateJavaScriptAsync($"factorial({number})");
resultLabel.Text = $"Factorial of {number} is {result}.";

WebView.EvaluateJavaScriptAsync メソッドは、引数として指定された JavaScript を評価し、結果を string として返します。 この例では、factorial JavaScript 関数が呼び出され、結果として number の階乗が返されます。 この JavaScript 関数は、WebView が読み込むローカル HTML ファイルで定義されており、次の例に示されています。

<html>
<body>
<script type="text/javascript">
function factorial(num) {
        if (num === 0 || num === 1)
            return 1;
        for (var i = num - 1; i >= 1; i--) {
            num *= i;
        }
        return num;
}
</script>
</body>
</html>

iOS および Mac Catalyst でネイティブ WebView を構成する

ネイティブ WebView コントロールは、WKWebView から派生した iOS と Mac Catalyst の MauiWKWebView です。 MauiWKWebView コンストラクターのオーバーロードの 1 つを使用すると WKWebViewConfiguration オブジェクトを指定できます。これにより、WKWebView オブジェクトの構成方法に関する情報が提供されます。 一般的な構成には、ユーザー エージェントの設定、Web コンテンツで使用できるようにする Cookie の指定、Web コンテンツへのカスタム スクリプトの挿入などがあります。

アプリに WKWebViewConfiguration オブジェクトを作成し、そのプロパティを必要に応じて構成できます。 または、静的 MauiWKWebView.CreateConfiguration メソッドを呼び出して .NET MAUI の WKWebViewConfiguration オブジェクトを取得し、それを変更することもできます。 その後、WKWebViewConfiguration オブジェクトを MauiWKWebView コンストラクター オーバーロードの引数として指定できます。

ハンドラーのプラットフォーム ビューが作成されると、iOS や Mac Catalyst ではネイティブ WebView の構成を変更できないため、カスタム ハンドラー ファクトリ デリゲートを作成して変更する必要があります。

#if IOS || MACCATALYST
using WebKit;
using CoreGraphics;
using Microsoft.Maui.Platform;
using Microsoft.Maui.Handlers;
#endif
...

#if IOS || MACCATALYST
    Microsoft.Maui.Handlers.WebViewHandler.PlatformViewFactory = (handler) =>
    {
        WKWebViewConfiguration config = MauiWKWebView.CreateConfiguration();
        config.ApplicationNameForUserAgent = "MyProduct/1.0.0";
        return new MauiWKWebView(CGRect.Empty, (WebViewHandler)handler, config);
    };
#endif

Note

WebView がアプリに表示される前に、WKWebViewConfiguration オブジェクトを使用して MauiWKWebView を構成する必要があります。 これを行うのに適した場所は、MauiProgram.csApp.xaml.cs などのアプリのスタートアップ パスにあります。

iOS および Mac Catalyst でメディアの再生設定を設定する

iOS と Mac Catalyst の WebView では、自動再生やピクチャ イン ピクチャを含む HTML5 ビデオのインライン メディア再生が既定で有効になっています。 この既定値を変更したり、他のメディア再生設定を設定したりするには、ハンドラーのプラットフォーム ビューを作成した後でメディア再生の基本設定を変更できないため、カスタム ハンドラー ファクトリ デリゲートを作成する必要があります。 次のコードは、これを行う例を示しています。

#if IOS || MACCATALYST
using WebKit;
using CoreGraphics;
using Microsoft.Maui.Platform;
using Microsoft.Maui.Handlers;
#endif
...

#if IOS || MACCATALYST
    Microsoft.Maui.Handlers.WebViewHandler.PlatformViewFactory = (handler) =>
    {
        WKWebViewConfiguration config = MauiWKWebView.CreateConfiguration();

        // True to play HTML5 videos inliine, false to use the native full-screen controller.
        config.AllowsInlineMediaPlayback = false;

        // True to play videos over AirPlay, otherwise false.
        config.AllowsAirPlayForMediaPlayback = false;

        // True to let HTML5 videos play Picture in Picture.
        config.AllowsPictureInPictureMediaPlayback = false;

        // Media types that require a user gesture to begin playing.
        config.MediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypes.All;

        return new MauiWKWebView(CGRect.Empty, (WebViewHandler)handler, config);
    };
#endif

iOS での WebView の構成の詳細については、「 iOS および Mac Catalyst でネイティブ WebView を構成する」を参照してください。

Mac Catalyst で WebView を検査する

Safari 開発者ツールを使用して Mac Catalyst 上の WebView のコンテンツを検査するには、アプリに次のコードを追加します。

#if MACCATALYST
        Microsoft.Maui.Handlers.WebViewHandler.Mapper.AppendToMapping("Inspect", (handler, view) =>
        {
            if (OperatingSystem.IsMacCatalystVersionAtLeast(16, 6))
                handler.PlatformView.Inspectable = true;
        });
#endif

このコードでは、Mac Catalyst 上の WebViewHandler のプロパティ マッパーをカスタマイズして、WebView コンテンツを Safari 開発者ツールで検査できるようにします。 ハンドラーの詳細については、「ハンドラー」を参照してください。

Mac Catalyst アプリで Safari 開発者ツールを使用するには、次の手順で行います。

  1. Mac で Safari を開きます。
  2. Safari で、[Safari] > [環境設定] > [詳細] > [メニュー バーに開発メニューを表示] チェックボックスを選択します。
  3. .NET MAUI Mac Catalyst アプリを実行します。
  4. Safari で、[開発] > [{デバイス名}] メニューを選択します。ここで、{Device name} プレースホルダーは Macbook Pro などのデバイス名です。 次に、アプリ名の下にあるエントリを選択します。これにより、実行中のアプリも強調表示されます。 その結果、[Web インスペクタ] ウィンドウが表示されます。

システム ブラウザーを起動する

Microsoft.Maui.Essentials で提供される Launcher クラスを使用して、システムの Web ブラウザーで URI を開くことができます。 ランチャーの OpenAsync メソッドを呼び出し、開く URI を表す string または Uri 引数を渡します。

await Launcher.OpenAsync("https://learn.microsoft.com/dotnet/maui");

詳細については、「ランチャー」を参照してください。