HTML & CSS 网站 - WebView 完全支持使用 HTML & CSS 编写的网站,包括 JavaScript 支持。
文档 - 由于 WebView 是使用每个平台上的本机组件实现的,因此 WebView 能够以基础平台支持的格式显示文档。
HTML 字符串 – WebView 可以显示内存中的 HTML 字符串。
本地文件 - WebView 可以呈现上述任何嵌入到应用中的内容类型。
WebView
Windows 不支持 Silverlight、Flash 或任何 ActiveX 控件,即使它们在该平台上受 Internet Explorer 支持也是如此。
若要显示来自 Internet 的网站,请将
WebView
的
Source
属性设置为字符串 URL:
var browser = new WebView
Source = "https://dotnet.microsoft.com/apps/xamarin"
URL 必须使用 (指定的协议完全形成,即它必须在) 前面附加“http://”或“https://”。
iOS 和 ATS
自版本 9 起,iOS 仅允许应用程序与默认实现最佳做法安全的服务器通信。 必须在 中 Info.plist
设置值才能启用与不安全服务器的通信。
如果应用程序需要连接到不安全的网站,则应始终使用 NSExceptionDomains
作为例外进入域,而不是使用 NSAllowsArbitraryLoads
完全关闭 ATS。 NSAllowsArbitraryLoads
应仅在极端紧急情况下使用。
下面演示了如何启用特定域 (在本例中 xamarin.com) 绕过 ATS 要求:
<key>NSAppTransportSecurity</key>
<key>NSExceptionDomains</key>
<key>xamarin.com</key>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
最佳做法是仅允许某些域绕过 ATS,使你能够使用受信任的站点,同时受益于不受信任的域的额外安全性。 下面演示了为应用禁用 ATS 的不太安全的方法:
<key>NSAppTransportSecurity</key>
<key>NSAllowsArbitraryLoads </key>
<true/>
</dict>
有关 iOS 9 中的这项新功能的详细信息,请参阅 应用传输安全性 。
HTML 字符串
如果要在代码中显示动态定义的 HTML 字符串,则需要创建 的 HtmlWebViewSource
实例:
var browser = new WebView();
var htmlSource = new HtmlWebViewSource();
htmlSource.Html = @"<html><body>
<h1>Xamarin.Forms</h1>
<p>Welcome to WebView.</p>
</body></html>";
browser.Source = htmlSource;
在上面的代码中, @
用于将 HTML 标记为 逐字字符串文本,这意味着将忽略大多数转义字符。
可能需要设置 WidthRequest
的 WebView
和 HeightRequest
属性才能查看 HTML 内容,具体取决于 的布局WebView
, 是其子元素。 例如,这在 中 StackLayout
是必需的。
本地 HTML 内容
WebView 可以显示嵌入在应用中的 HTML、CSS 和 JavaScript 中的内容。 例如:
<title>Xamarin Forms</title>
</head>
<h1>Xamarin.Forms</h1>
<p>This is an iOS web page.</p>
<img src="XamarinLogo.png" />
</body>
</html>
html,body {
margin:0;
padding:10;
body,p,h1 {
font-family: Chalkduster;
请注意,需要为每个平台自定义上述 CSS 中指定的字体,因为并非每个平台都具有相同的字体。
若要使用 WebView
显示本地内容,需要像打开任何其他文件一样打开 HTML 文件,然后将内容作为字符串加载到 Html
的 属性中 HtmlWebViewSource
。 有关打开文件的详细信息,请参阅 使用文件。
以下屏幕截图显示了在每个平台上显示本地内容的结果:
虽然已加载第一页,但 WebView
不知道 HTML 来自何处。 处理引用本地资源的页面时,这是一个问题。 可能发生这种情况的示例包括本地页面相互链接、页面使用单独的 JavaScript 文件或链接到 CSS 样式表的页面。
若要解决此问题,需要告知 WebView
在文件系统上查找文件的位置。 为此,请BaseUrl
设置 所使用的 WebView
上的 HtmlWebViewSource
属性。
由于每个操作系统上的文件系统不同,因此需要确定每个平台上的 URL。 Xamarin.Forms 公开用于 DependencyService
在每个平台上的运行时解析依赖项的 。
若要使用 DependencyService
,请首先定义可在每个平台上实现的接口:
public interface IBaseUrl { string Get(); }
请注意,在每个平台上实现 接口之前,应用将不会运行。 在通用项目中,请确保记得使用 DependencyService
设置 BaseUrl
:
var source = new HtmlWebViewSource();
source.BaseUrl = DependencyService.Get<IBaseUrl>().Get();
然后,必须为每个平台提供 接口的实现。
在 iOS 上,Web 内容应位于项目的根目录或带有生成操作 BundleResource的资源目录中,如下所示:
Visual Studio
Visual Studio for Mac
BaseUrl
应将 设置为main捆绑包的路径:
[assembly: Dependency (typeof (BaseUrl_iOS))]
namespace WorkingWithWebview.iOS
public class BaseUrl_iOS : IBaseUrl
public string Get()
return NSBundle.MainBundle.BundlePath;
Android
在 Android 上,使用生成操作 AndroidAsset 将 HTML、CSS 和图像放置在 Assets 文件夹中,如下所示:
Visual Studio
Visual Studio for Mac
在 Android 上 BaseUrl
, 应设置为 "file:///android_asset/"
:
[assembly: Dependency (typeof(BaseUrl_Android))]
namespace WorkingWithWebview.Android
public class BaseUrl_Android : IBaseUrl
public string Get()
return "file:///android_asset/";
在 Android 上,还可以通过当前 Android 上下文访问 Assets 文件夹中的文件,该上下文由 MainActivity.Instance
属性公开:
var assetManager = MainActivity.Instance.Assets;
using (var streamReader = new StreamReader (assetManager.Open ("local.html")))
var html = streamReader.ReadToEnd ();
在通用 Windows 平台 (UWP) 项目上,将 HTML、CSS 和图像放在项目根目录中,并将生成操作设置为“内容”。
BaseUrl
应将 设置为 "ms-appx-web:///"
:
[assembly: Dependency(typeof(BaseUrl))]
namespace WorkingWithWebview.UWP
public class BaseUrl : IBaseUrl
public string Get()
return "ms-appx-web:///";
WebView 支持通过它提供的几种方法和属性进行导航:
GoForward () – 如果 CanGoForward
为 true,则调用 GoForward
将向前导航到下一个访问的页面。
GoBack () – 如果 CanGoBack
为 true,调用 GoBack
将导航到上次访问的页面。
CanGoBack – true
如果有页面要导航回, false
如果浏览器位于起始 URL,
CanGoForward – true
如果用户已向后导航,并且可以向前移动到已访问的页面。
在页面中, WebView
不支持多点触控手势。 请务必确保内容经过移动优化且无需缩放即可显示。
应用程序通常会在 而不是 WebView
设备的浏览器中显示链接。 在这些情况下,允许正常导航很有用,但当用户在起始链接上时回击时,应用应返回到普通应用视图。
使用内置导航方法和属性启用此方案。
首先创建浏览器视图的页面:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WebViewSample.InAppBrowserXaml"
Title="Browser">
<StackLayout Margin="20">
<StackLayout Orientation="Horizontal">
<Button Text="Back" HorizontalOptions="StartAndExpand" Clicked="OnBackButtonClicked" />
<Button Text="Forward" HorizontalOptions="EndAndExpand" Clicked="OnForwardButtonClicked" />
</StackLayout>
<!-- WebView needs to be given height and width request within layouts to render. -->
<WebView x:Name="webView" WidthRequest="1000" HeightRequest="1000" />
</StackLayout>
</ContentPage>
在代码隐藏中:
public partial class InAppBrowserXaml : ContentPage
public InAppBrowserXaml(string URL)
InitializeComponent();
webView.Source = URL;
async void OnBackButtonClicked(object sender, EventArgs e)
if (webView.CanGoBack)
webView.GoBack();
await Navigation.PopAsync();
void OnForwardButtonClicked(object sender, EventArgs e)
if (webView.CanGoForward)
webView.GoForward();
就这么简单!
WebView 引发以下事件,以帮助你响应状态更改:
Navigating
– WebView 开始加载新页面时引发的事件。
Navigated
- 加载页面且导航已停止时引发的事件。
ReloadRequested
– 发出重新加载当前内容的请求时引发的事件。
WebNavigatingEventArgs
事件附带的对象Navigating
有四个属性:
Cancel
– 指示是否取消导航。
NavigationEvent
– 引发的导航事件。
Source
– 执行导航的元素。
Url
– 导航目标。
WebNavigatedEventArgs
事件附带的对象Navigated
有四个属性:
NavigationEvent
– 引发的导航事件。
Result
– 使用 WebNavigationResult
枚举成员描述导航的结果。 有效值为 Cancel
、Failure
、Success
和 Timeout
。
Source
– 执行导航的元素。
Url
– 导航目标。
如果预计使用加载时间较长的网页,请考虑使用 Navigating
和 Navigated
事件来实现状态指示器。 例如:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WebViewSample.LoadingLabelXaml"
Title="Loading Demo">
<StackLayout>
<!--Loading label should not render by default.-->
<Label x:Name="labelLoading" Text="Loading..." IsVisible="false" />
<WebView HeightRequest="1000" WidthRequest="1000" Source="https://dotnet.microsoft.com/apps/xamarin" Navigated="webviewNavigated" Navigating="webviewNavigating" />
</StackLayout>
</ContentPage>
两个事件处理程序:
void webviewNavigating(object sender, WebNavigatingEventArgs e)
labelLoading.IsVisible = true;
void webviewNavigated(object sender, WebNavigatedEventArgs e)
labelLoading.IsVisible = false;
这会导致以下输出 (加载) :
已完成加载:
重新加载内容
WebView
Reload
具有可用于重新加载当前内容的方法:
var webView = new WebView();
webView.Reload();
Reload
调用 方法时,ReloadRequested
将触发 事件,指示已发出重新加载当前内容的请求。
常用的 Web 浏览器采用硬件加速渲染和 JavaScript 编译等技术。 在 Xamarin.Forms 4.4 之前, Xamarin.FormsWebView
由 UIWebView
类在 iOS 上实现。 但是,其中许多技术在此实现中不可用。 因此,自 4.4 起 Xamarin.Forms , Xamarin.FormsWebView
由 WkWebView
类在 iOS 上实现,该类支持更快的浏览。
在 iOS 上 WkWebViewRenderer
, 具有接受 参数的 WkWebViewConfiguration
构造函数重载。 这样就可以在创建时配置呈现器。
出于兼容性原因,应用程序可以返回到使用 iOS UIWebView
类来实现 Xamarin.FormsWebView
。 这可以通过将以下代码添加到应用程序的 iOS 平台项目中的 AssemblyInfo.cs 文件来实现:
// Opt-in to using UIWebView instead of WkWebView.
[assembly: ExportRenderer(typeof(Xamarin.Forms.WebView), typeof(Xamarin.Forms.Platform.iOS.WebViewRenderer))]
在 Xamarin.Forms 5.0 中 WebViewRenderer
, 类已被删除。 因此, Xamarin.Forms 5.0 不包含对 控件的 UIWebView
引用。
WebView
默认情况下,Android 上的速度与内置浏览器的速度一样快。
UWP WebView 使用 Microsoft Edge 呈现引擎。 台式机和平板电脑设备应看到与使用 Edge 浏览器本身相同的性能。
若要 WebView
正常工作,必须确保为每个平台设置权限。 请注意,在某些平台上, WebView
将在调试模式下工作,但在为发布而构建时则不起作用。 这是因为某些权限(如 Android 上用于 Internet 访问的权限)默认在调试模式下Visual Studio for Mac设置。
UWP - 显示网络内容时需要 Internet (客户端 & 服务器) 功能。
Android – 仅当显示来自网络的内容时才需要 INTERNET
。 本地内容不需要特殊权限。
iOS - 不需要特殊权限。
Layout
与大多数其他 Xamarin.Forms 视图不同, WebView
要求 HeightRequest
在包含在 StackLayout 或 RelativeLayout 中时指定 和 WidthRequest
。 如果未能指定这些属性, WebView
将不会呈现 。
以下示例演示了可导致工作、呈现 WebView
的布局:
带 WidthRequest & HeightRequest 的 StackLayout:
<StackLayout>
<Label Text="test" />
<WebView Source="https://dotnet.microsoft.com/apps/xamarin"
HeightRequest="1000"
WidthRequest="1000" />
</StackLayout>
带 WidthRequest & HeightRequest 的 RelativeLayout:
<RelativeLayout>
<Label Text="test"
RelativeLayout.XConstraint= "{ConstraintExpression
Type=Constant, Constant=10}"
RelativeLayout.YConstraint= "{ConstraintExpression
Type=Constant, Constant=20}" />
<WebView Source="https://dotnet.microsoft.com/apps/xamarin"
RelativeLayout.XConstraint="{ConstraintExpression Type=Constant,
Constant=10}"
RelativeLayout.YConstraint="{ConstraintExpression Type=Constant,
Constant=50}"
WidthRequest="1000" HeightRequest="1000" />
</RelativeLayout>
不带 WidthRequest & HeightRequest 的 AbsoluteLayout:
<AbsoluteLayout>
<Label Text="test" AbsoluteLayout.LayoutBounds="0,0,100,100" />
<WebView Source="https://dotnet.microsoft.com/apps/xamarin"
AbsoluteLayout.LayoutBounds="0,150,500,500" />
</AbsoluteLayout>
不带 WidthRequest & HeightRequest 的网格。 网格是少数不需要指定请求的高度和宽度的布局之一:
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Text="test" Grid.Row="0" />
<WebView Source="https://dotnet.microsoft.com/apps/xamarin" Grid.Row="1" />
</Grid>
调用 JavaScript
WebView
包括从 C# 调用 JavaScript 函数并将任何结果返回给调用的 C# 代码的功能。 这是使用 WebView.EvaluateJavaScriptAsync
方法完成的,如 WebView 示例中的以下示例所示:
var numberEntry = new Entry { Text = "5" };
var resultLabel = new Label();
var 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 函数在 加载的本地 HTML 文件中 WebView
定义,并在以下示例中显示:
<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>
Cookie
可以在 上 WebView
设置 Cookie,然后将 Cookie 与 Web 请求一起发送到指定的 URL。 这是通过将 对象添加到 Cookie
CookieContainer
,然后将其设置为可绑定属性的值来实现。WebView.Cookies
下面的代码显示了此用法的示例:
using System.Net;
using Xamarin.Forms;
// ...
CookieContainer cookieContainer = new CookieContainer();
Uri uri = new Uri("https://dotnet.microsoft.com/apps/xamarin", UriKind.RelativeOrAbsolute);
Cookie cookie = new Cookie
Name = "XamarinCookie",
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
当 将 Web 请求发送到指定的 URL 时,Cookie 随请求一起发送。
UIWebView 弃用和App Store拒绝 (ITMS-90809)
从 2020 年 4 月开始, Apple 将拒绝 仍使用已 UIWebView
弃用 API 的应用。 虽然 Xamarin.Forms 已将 切换 WKWebView
为 默认值,但二进制文件中仍有对旧 SDK 的 Xamarin.Forms 引用。 当前 iOS 链接器行为不会删除此行为,因此当你提交到App Store时,弃用的 UIWebView
API 仍会显示为从你的应用中引用。
在 Xamarin.Forms 5.0 中 WebViewRenderer
, 类已被删除。 因此, Xamarin.Forms 5.0 不包含对 控件的 UIWebView
引用。
链接器预览版可用于解决此问题。 若要启用预览,需要向链接器提供其他参数 --optimize=experimental-xforms-product-type
。
执行此操作的先决条件是:
Xamarin.Forms 4.5 或更高版本。 Xamarin.Forms 如果你的应用使用材料视觉对象,则需要 4.6 或更高版本。
Xamarin.iOS 13.10.0.17 或更高版本。 在 Visual Studio 中检查 Xamarin.iOS 版本。 此版本的 Xamarin.iOS 包含在 Visual Studio for Mac 8.4.1 和 Visual Studio 16.4.3 中。
删除对 的UIWebView
引用。 代码不应具有对 UIWebView
或使用 的任何类的任何 UIWebView
引用。
有关检测和删除 UIWebView
引用的详细信息,请参阅 UIWebView 弃用。
Visual Studio
Visual Studio for Mac
打开 iOS 项目属性 – 右键单击 iOS 项目,然后选择 “属性”。
导航到“iOS 生成”部分 – 选择“ iOS 生成 ”部分。
更新其他 mtouch 参数 – 在 “其他 mtouch 参数 ”中,除了可能已存在于) 的任何值外, (添加此标志 --optimize=experimental-xforms-product-type
。 注意:此标志可与“ 链接器行为 ”设置为 “仅 SDK” 或“ 全部链接”一起使用。 如果出于任何原因,在将链接器行为设置为“全部”时看到错误,这很可能是应用代码或第三方库中的一个链接器不安全的问题。 有关链接器的详细信息,请参阅 链接 Xamarin.iOS 应用。
更新所有生成配置 - 使用窗口顶部的 “配置” 和 “平台 ”列表更新所有生成配置。 要更新的最重要配置是 Release/iPhone 配置,因为它通常用于为App Store提交创建内部版本。
在此屏幕截图中,可以看到具有新标志的窗口:
打开 iOS 项目选项 – 右键单击 iOS 项目,然后选择 “选项”。
导航到“iOS 生成”部分 – 选择“ iOS 生成 ”部分。
更新其他 mtouch 参数 – 在 “其他 mtouch 参数 ”中,除了可能已存在于) 的任何值外, (添加此标志 --optimize=experimental-xforms-product-type
。 注意:此标志可与“ 链接器行为 ”设置为 “仅 SDK” 或“ 全部链接”一起使用。 如果出于任何原因,在将链接器行为设置为“全部”时看到错误,这很可能是应用代码或第三方库中的一个链接器不安全的问题。 有关链接器的详细信息,请参阅 链接 Xamarin.iOS 应用。
更新所有生成配置 - 使用窗口顶部的 “配置” 和 “平台 ”列表更新所有生成配置。 要更新的最重要配置是 Release/iPhone 配置,因为它通常用于为App Store提交创建内部版本。
在此屏幕截图中,可以看到具有新标志的窗口: