在 WebView2 应用中使用帧
框架允许你将其他网页嵌入到自己的网页中。 框架是网页中的子页面或区域,类似于网页中的网页。
iframe 是一种类型的帧。 其他类型的帧包括 frameset
、、portal
embed
、 fencedFrame
和 object
。 帧main WebView2 类型为 CoreWebView2Frame
,当前为顶级 iframe 启用。 计划支持其他类型的帧。
WebView2 支持与 iframe 交互的 API。 可以执行下列操作:
- 了解何时创建 iframe。
- 了解 iframe 何时导航到其他 URL。 这与 WebView2 应用的状态机导航事件相同。
- 在主机应用和 iframe 之间进行通信,双向发送消息。
- 允许应用忽略
X-Frame-Options
HTTP 响应标头。
另请参阅:
- WebView2 功能和 API 概述中的 iframe。
- HTML <iframe> 标记
订阅 FrameCreated 事件以获取帧
若要与主机应用中的帧交互,第一步是订阅 FrameCreated
事件,以便主机应用获取帧对象。 每当创建新帧时,将 FrameCreated
引发该事件。 主机应用获取帧对象后,使用帧对象监视更改并与此特定帧交互。
主机应用必须通过订阅事件来 CoreWebView2Frame.Destroyed
监视帧的生存期,因为当帧被销毁时,主机应用无法再引用该帧。 在每个新网页导航期间,都会创建和销毁帧。
CoreWebView2Frame.IsDestroyed
使用 方法检查帧是否仍然存在。
另请参阅:
- WebView2 功能和 API 概述中的 iframe。
在框架内导航
创建框架后,框架将导航到框架的源 URL。 iframe 使用导航和导航事件,例如 FrameNavigationStarting
和 NavigationCompleted
。 当框架导航到源 URL 时,将引发以下导航事件:
NavigationStarting
ContentLoading
HistoryChanged
DOMContentLoaded
NavigationCompleted
在框架内导航的频率
导航可能会在框架中发生。 作为一个简单的用例, iframe
元素的 source
属性是一个 URL(如 wikipedia.com),该 URL 加载到 iframe 中。 通常,导航会在创建框架后立即发生。
ContentLoading
然后引发 、 DOMContentLoaded
和 NavigationCompleted
事件。
框架本身正在导航。 网页导航到 URL。 同样,帧可能会导航。
创建框架后,框架将按照主机应用的驱动方式进行导航。 若要监视main页中发生的情况,事件(如 NavigationStarting
、 NavigationCompleted
),并使HistoryChanged
主机应用能够在框架或网页之间来回导航。 框架导航到新 URL 的频率低于网页,但支持相同的导航样式。 用户通常无法在框架内导航,尽管 JavaScript 支持该操作:框架在导航方面通常是静态的。
另请参阅:
- WebView2 应用的导航事件中的标准事件序列。
- CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync 方法 - 此方法可用于 iframe 和网页。 脚本必须检查它是否在 iframe 中。
导航事件:
对于重复的等效 NavigationStarting
项和 NavigationCompleted
事件,建议使用 上的 CoreWebView2Frame
事件,而不是上的 CoreWebView2
等效的取代事件,因为 类型 CoreWebView2Frame
支持更多方案,以允许与帧交互。
另请参阅:
在 iframe 中使用主机对象
若要在主机应用的本机端与 iframe 中的 JavaScript 之间进行通信,请使用主机对象。 主机对象是在主机应用中创建的对象,然后从应用的网页端的 JavaScript 代码使用。
通过主机对象从框架中的脚本使用本机端 API 类似于从 Web 端代码调用本机端代码中所述的 Web/本机互操作页面结构:
若要在 iframe 中使用主机对象,请执行以下操作:
- 定义主机对象并实现
IDispatch
。 - 使用
AddHostObjectToScriptWithOrigins
(Win32) 或AddHostObjectToScript
(.NET) 在本机端添加主机对象。 - 在 Web 端代码中的 JavaScript 中,使用
chrome.webview.hostObjects.<name>
API 访问此主机对象。
若要从框架中的 Web 端 JavaScript 访问和控制本机端对象,请使用 AddHostObjectToScriptWithOrigins
(Win32) 或 CoreWebView2Frame.AddHostObjectToScript
(.NET) ,其中包含 参数 origins
。 参数 origins
指定出于安全原因,允许 iframe 访问哪些 URL。 此参数标识 iframe 将有权访问主机对象的 URL。
如果框架导航到不在 origins
列表中的 URL,则帧将无法操作宿主对象;该帧将无法读取或写入任何属性。
请参阅框架 方法 中 AddHostObjectToScript
的方法名称表。 请参阅以下两行:
-
applyHostFunction
、getHostProperty
和setHostProperty
。 -
getLocalProperty
和setLocalProperty
。
-
CoreWebView2Frame.AddHostObjectToScript 方法 - 具有 参数
origins
。 文档没有 方法名称 表。
上述方法的工作方式类似于以下方法:
-
CoreWebView2.AddHostObjectToScript 方法。 请参阅 方法名称 表。 读取这两个
origins
API 参考主题,尽管对于帧,应改用支持 参数的方法。
示例代码
请参阅从 Web 端代码调用本机代码中的步骤 6:调用 AddHostObjectToScript 以将主机对象传递到Web 端代码。
另请参阅:
- WebView2 功能和 API 概述中的主机/Web 对象共享。
发送和接收消息
可以在本机应用与 iframe 中的 JavaScript 代码之间发送消息:
- 可以将消息从 HTML 页的 iframe 中的 JavaScript 发送到主机应用。
- 可以将消息从主机应用发送到 HTML 页的 iframe 中的 JavaScript。
将 Web 消息从 iframe 发送到主机应用
若要将 Web 消息从 iframe 发送到主机应用,请使用 window.chrome.webview.postMessage
方法:
window.chrome.webview.postMessage(`SetTitleText ${titleText.value}`);
若要在主机应用中接收这些消息,主机应用必须订阅 WebMessageReceived event
。
将消息从主机应用发送到 iframe
主机应用通过调用 PostWebMessageAsJson
或 PostWebMessageAsString
方法将消息发送到 iframe。
iframe 通过订阅 window.chrome.webview.addEventListener('message')
事件来接收消息,如下所示:
window.chrome.webview.addEventListener('message', arg => {
// implement event listener here
});
另请参阅:
- 本机端和 Web 端代码的互操作
- WebView2 功能和 API 概述中的 Web消息传送。
使用 ExecuteScript 在 iframe 中运行 JavaScript 代码
WebView2 应用可以使用 在框架 ExecuteScript
中运行任何 JavaScript。
若要在 iframe 中运行脚本,必须创建执行上下文。 执行上下文是在事件之后 ContentLoading
创建的,因此,如果在 ExecuteScript
引发事件之前 ContentLoading
调用 ,脚本将不会运行,并且将返回字符串 null
。
有关事件的信息 ContentLoading
,请参阅 WebView2 应用的导航事件,该事件对框架和网页有效。
另请参阅:
- WebView2 功能和 API 概述中的脚本执行。
使用 WebResourceRequested
iframe 中的 事件修改网络事件
对于 iframe,可以使用 事件侦听网络事件并对其进行 WebResourceRequested
修改。
另请参阅:
- 在 WebView2功能和 API 概述中管理 WebView2 中的网络请求。
- 网络请求的自定义管理
- WebView2 SDK 的存档发行说明中用于 1.0.1222-prerelease 的实验性 API。
请参阅最新的预发行版 API。 以下链接包含 1.0.1466-prerelease
。 在 API 参考文档左上角的 “版本 ”下拉列表中,选择最新的预发行版。
-
CoreWebView2.AddWebResourceRequestedFilter (uri、resourceContext、requestSourceKinds) 方法重载 - 若要订阅属于 iframe 的网络请求,必须使用此重载并将 用作
Document
参数的值requestSourceKinds
。 - CoreWebView2.RemoveWebResourceRequestedFilter (uri、resourceContext、requestSourceKinds) 方法重载
- CoreWebView2WebResourceRequestedEventArgs 类
忽略 X-Frame-Options 以在框架内呈现网页
X-Frame-Options
网页使用 HTTP 响应标头来防止应用程序在框架内呈现该网页。 属性 AdditionalAllowedFrameAncestors
允许应用程序绕过 X-Frame-Options
标头,在框架内呈现网页。
另请参阅:
在主机应用中使用 iframe 的示例
此示例代码演示如何使用帧 API,包括:
FrameCreated
CoreWebView2FrameCreatedEventArgs
DOMContentLoaded
CoreWebView2DOMContentLoadedEventArgs
ExecuteScript
此示例代码从 WebView2WpfBrowser 示例中的 MainWindow.xaml.cs精简。
void DOMContentLoadedCmdExecuted(object target, ExecutedRoutedEventArgs e)
{
// Subscribe to the FrameCreated event to obtain the frame object when
// it's created.
webView.CoreWebView2.FrameCreated += WebView_FrameCreatedDOMContentLoaded;
webView.NavigateToString(@"<!DOCTYPE html>" +
"<h1>DOMContentLoaded sample page</h1>" +
"<h2>The content to the iframe and below will be added after DOM content is loaded </h2>" +
"<iframe style='height: 200px; width: 100%;'/>");
}
void WebView_FrameCreatedDOMContentLoaded(object sender, CoreWebView2FrameCreatedEventArgs args)
{
// In order for ExecuteScriptAsync to successfully run inside the iframe,
// subscribe to the ContentLoading or DOMContentLoaded event. Once these
// events are raised, you can call ExecuteScriptAsync.
args.Frame.DOMContentLoaded += (frameSender, DOMContentLoadedArgs) =>
{
args.Frame.ExecuteScriptAsync(
"let content = document.createElement(\"h2\");" +
"content.style.color = 'blue';" +
"content.textContent = \"This text was added to the iframe by the host app\";" +
"document.body.appendChild(content);");
};
}
API 参考概述
WebView2 功能和 API 概述中列出的以下功能包括与帧相关的 API:
另请参阅
- 从 Web 端代码调用本机端代码
- WebView2 应用的导航事件 - 对框架和网页有效。
外部页面: