.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
对象。
自版本 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="<HTML><BODY><H1>.NET MAUI</H1><P>Welcome to WebView.</P></BODY><HTML>" />
</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 支持使用 GoBack
和 GoForward
方法进行编程导航。 这些方法支持浏览 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
,页面导航启动时触发。 与 WebNavigatingEventArgs
事件相关联的 Navigating
对象定义了一个 Cancel
类型的 bool
属性,可用于取消导航。
Navigated
会在页面导航完成时引发。
WebNavigatedEventArgs
对象伴随 Navigated
事件,定义了一个 Result
类型的 WebNavigationResult
属性,该属性指示导航结果。
导航到在 Android 上打开新窗口的内容
在 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 控件是 MauiWKWebView
,它派生自 WKWebView
。
MauiWKWebView
构造函数重载之一允许指定 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.cs 或 App.xaml.cs。
在 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 的 string
或 Uri
参数:
await Launcher.OpenAsync("https://learn.microsoft.com/dotnet/maui");
有关详细信息,请参阅 Launcher。