添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

.NET 多平台应用 UI (.NET MAUI) WebView 在应用中显示远程网页、本地 HTML 文件和 HTML 字符串。 在 WebView 显示的内容包括对级联样式表(CSS)和 JavaScript 的支持。 默认情况下,.NET MAUI 项目包含显示远程网页所需的平台权限,以便 WebView 能够展示这些网页。

WebView 定义以下属性:

Cookies ,类型为 CookieContainer ,提供用于储存 Cookie 集合体的空间。 CanGoBack ,类型为 bool ,指示用户是否可以导航到以前的页面。 这是一个只读属性。 CanGoForward ,类型为 bool ,指示用户是否可以向前导航。 这是一个只读属性。 Source 属于 WebViewSource 类型,表示 WebView 所显示的位置。 UserAgent ,属于 string 类型,表示用户代理。 默认值是基础平台浏览器的用户代理,如果无法确定,则为 null 值。

这些属性由 BindableProperty 对象提供支持,这意味着这些属性可以是数据绑定的目标,并设置样式。

Source 属性可以设置为 UrlWebViewSource 对象或 HtmlWebViewSource 对象,这两个对象都派生自 WebViewSource UrlWebViewSource 用于加载使用 URL 指定的网页,而 HtmlWebViewSource 对象用于加载本地 HTML 文件或本地 HTML。

WebView 定义在页面导航启动时引发的 Navigating 事件,以及页面导航完成后引发的 Navigated 事件。 与 WebNavigatingEventArgs 事件相关联的 Navigating 对象定义了一个 Cancel 类型的 bool 属性,可用于取消导航。 WebNavigatedEventArgs 对象伴随 Navigated 事件,定义了一个 Result 类型的 WebNavigationResult 属性,该属性指示导航结果。

WebView 定义以下事件:

Navigating ,在页面导航启动时引发。 伴随此事件的 WebNavigatingEventArgs 对象定义了一个 Cancel 类型的 bool 属性,可用于取消导航。 Navigated ,在页面导航完成时触发。 附带此事件的 WebNavigatedEventArgs 对象定义了一个 Result 类型的 WebNavigationResult 属性,用于指示导航结果。 ProcessTerminated ,会在 WebView 进程意外结束时被引发。 此事件附带的 WebViewProcessTerminatedEventArgs 对象定义特定于平台的属性,这些属性指示进程失败的原因。

当包含在 WebView HeightRequest WidthRequest 中时, HorizontalStackLayout 必须指定其 StackLayout VerticalStackLayout 属性。 如果无法指定这些属性,则 WebView 将不会呈现。

若要显示远程网页,请将 Source 属性设置为一个能够指定 URI 的 string

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

等效的 C# 代码为:

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

URI 必须使用指定的通信协议完整构建。

尽管 Source 属性的类型为 WebViewSource,但该属性可以设置为基于字符串的 URI。 这是因为 .NET MAUI 包括类型转换器和隐式转换运算符,用于将基于字符串的 URI 转换为 UrlWebViewSource 对象。

在 iOS 和 Mac Catalyst 上配置应用传输安全性

自版本 9 起,iOS 仅允许应用与安全服务器通信。 应用必须选择启用与不安全服务器的通信。

以下 Info.plist 配置演示如何启用特定域以绕过 Apple Transport Security (ATS) 要求:

	<key>NSAppTransportSecurity</key>
		<key>NSExceptionDomains</key>
			<key>mydomain.com</key>
				<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>
		<key>NSAllowsArbitraryLoads</key>
		<true/>
	</dict>

如果您的应用程序需要连接到不安全的网站,您应始终将域名作为例外使用 NSExceptionDomains 键输入,而不是完全关闭 ATS 使用 NSAllowsArbitraryLoads 键。

显示本地 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 字符串由于转义 <> 符号而变得不可读。 因此,为了提高可读性,可以在 CDATA 部分中内联 HTML:

<WebView>
    <WebView.Source>
        <HtmlWebViewSource>
            <HtmlWebViewSource.Html>
                <![CDATA[
                <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。 然后,该文件可以从在 HtmlWebViewSource 对象中定义的内联 HTML 中加载,该对象被设置为 Source 属性的值。

<WebView>
    <WebView.Source>
        <HtmlWebViewSource>
            <HtmlWebViewSource.Html>
                <![CDATA[
                </head>
                <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 生成操作添加到应用项目中,则本地 HTML 文件可以加载级联样式表(CSS)、JavaScript 和图像。

有关原始资产的详细信息,请参阅 原始资产

重新加载内容

WebView 有一个 Reload 方法,可以调用该方法来重新加载其源:

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

调用 Reload 方法时,将触发 ReloadRequested 事件,指示已发出重新加载当前内容的请求。

WebView 支持使用 GoBackGoForward 方法进行编程导航。 这些方法支持浏览 WebView 页面堆栈,并且只能在检查 CanGoBackCanGoForward 属性的值后调用:

WebView webView = new WebView();
// Go backwards, if allowed.
if (webView.CanGoBack)
    webView.GoBack();
// Go forwards, if allowed.
if (webView.CanGoForward)
    webView.GoForward();

当页面导航(无论是由编程方式启动还是由用户启动)发生在 WebView时,会触发以下事件:

Navigating,页面导航启动时触发。 与 WebNavigatingEventArgs 事件相关联的 Navigating 对象定义了一个 Cancel 类型的 bool 属性,可用于取消导航。 Navigated会在页面导航完成时引发。 WebNavigatedEventArgs 对象伴随 Navigated 事件,定义了一个 Result 类型的 WebNavigationResult 属性,该属性指示导航结果。

在 Android 上,当按下指定 target="_blank"(在新窗口中打开内容)的超链接时,导航不会出现在 WebView 中。 这是因为在新窗口中打开超链接需要实现 OnCreateWindow,而 .NET MAUI 则不需要实现该超链接。 因此,对于此方案,应决定是自行实现 OnCreateWindow、在系统浏览器中打开 URL 还是执行其他操作。

或者,若要强制所有超链接在同一 WebView中打开,请在应用中修改 WebViewHandler,以便本机 WebView 禁用对多个窗口的支持:

#if ANDROID
    Microsoft.Maui.Handlers.WebViewHandler.Mapper.AppendToMapping("SupportMultipleWindows", (handler, view) =>
        handler.PlatformView.Settings.SetSupportMultipleWindows(false);
#endif

此代码通过使用 false 参数调用 SetSupportMultipleWindows 方法来自定义 Android 上的 WebViewHandler 的属性映射器,并且应在用户导航到指定 target="_blank"的超链接之前执行。 有关处理程序的详细信息,请参阅 处理程序

管理 Android 上的权限

浏览到请求访问设备录制硬件(如相机或麦克风)的页面时,WebView 控件必须授予权限。 WebView 控件使用 Android 上的 Android.Webkit.WebChromeClient 类型来响应权限请求。 但是,.NET MAUI 提供的 WebChromeClient 实现将忽略权限请求。 必须创建一个新类型,该类型继承自 MauiWebChromeClient 并批准权限请求。

自定义 WebView 来批准权限请求(使用这种方法)需要 Android API 26 或更高版本。

从网页到 WebView 控件的权限请求不同于从 .NET MAUI 应用向用户发出的权限请求。 针对整个应用,用户请求并批准 .NET MAUI 应用权限。 WebView 控件依赖于应用程序访问硬件的能力。 为了更好地说明这个概念,请考虑一个请求访问设备摄像头的网页。 即使该请求获得了 WebView 控制的批准,然而如果 .NET MAUI 应用没有得到用户批准访问相机,那么网页仍然无法访问相机。

以下步骤演示如何截获来自 WebView 控件的权限请求以使用相机。 如果尝试使用麦克风,则步骤将类似,只是使用与麦克风相关的权限,而不是与相机相关的权限。

  • 首先,将所需的应用权限添加到 Android 清单。 打开 平台/Android/AndroidManifest.xml 文件,并在 manifest 节点中添加以下内容:

    <uses-permission android:name="android.permission.CAMERA" />
    
  • 在应用中的某些时间点(例如加载包含 WebView 控件的页面时),请求用户允许应用访问相机的权限。

    private async Task RequestCameraPermission()
        PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.Camera>();
        if (status != PermissionStatus.Granted)
            await Permissions.RequestAsync<Permissions.Camera>();
    
  • 将以下类添加到 Platforms/Android 文件夹中,更改根命名空间以匹配项目的命名空间(不要将 .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();
                        request.Grant(request.GetResources());
                    return;
            base.OnPermissionRequest(request);
    

    在前面的代码片段中,MyWebChromeClient 类继承自 MauiWebChromeClient,并重写了 OnPermissionRequest 方法,以拦截网页权限请求。 检查每个权限项,以查看它是否与表示相机的 PermissionRequest.ResourceVideoCapture 字符串常量匹配。 如果匹配相机权限,代码将检查应用是否有权使用相机。 如果具有权限,网页请求将被批准。

  • 使用 Android SetWebChromeClient 控件上的 WebView 方法将 chrome 客户端设置为 MyWebChromeClient。 以下两项演示如何设置 chrome 客户端:

  • 给定一个名为 WebView的 .NET MAUI 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

    可以在 WebView 上设置 Cookie,以便使用 Web 请求将其发送到指定的 URL。 通过将 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() };
    

    在此示例中,将一个 Cookie 添加到 CookieContainer 对象,然后将其作为值设置到 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 文件中定义,并显示在以下示例中:

    <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

    iOS 和 Mac Catalyst 上的本机 WebView 控件是 MauiWKWebView,它派生自 WKWebViewMauiWKWebView 构造函数重载之一允许指定 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
    

    在应用中显示 MauiWKWebView 之前,您应先用 WKWebViewConfiguration 对象配置 WebView。 要执行此操作的适当位置位于应用的启动路径中,例如 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 属性映射器,以便使用 Safari 开发人员工具检查 WebView 的内容。 有关处理程序的详细信息,请参阅 处理程序

    若要将 Safari 开发人员工具用于 Mac Catalyst 应用,请执行以下操作:

  • 在 Mac 上打开 Safari。
  • 在 Safari 中,依次选择 Safari >“设置”、>“高级”,然后选中菜单栏中的>“显示开发菜单” 复选框。
  • 运行 .NET MAUI Mac Catalyst 应用。
  • 在 Safari 中,选择 开发 > {设备名称} 菜单,其中 {Device name} 占位符是你的设备名称,例如 Macbook Pro。 然后选择应用名称下的条目,该条目还会突出显示正在运行的应用。 这将导致 Web 检查器 窗口出现。
  • 启动系统浏览器

    可以使用 Launcher提供的 Microsoft.Maui.Essentials 类在系统 Web 浏览器中打开 URI。 调用启动器 OpenAsync 方法,并传入表示要打开的 URI 的 stringUri 参数:

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

    有关详细信息,请参阅 Launcher

  •