相关文章推荐
重感情的番茄  ·  使用阿里云CLI Visual ...·  7 月前    · 
热情的橡皮擦  ·  亚马逊 android S3 ...·  10 月前    · 
飞奔的可乐  ·  【java.lang.ClassFormat ...·  1 年前    · 

框架允许你将其他网页嵌入到自己的网页中。 框架 是网页中的子页面或区域,类似于网页中的网页。

iframe 是一种类型的帧。 其他类型的帧包括 frameset 、、 portal embed fencedFrame object 。 帧的主要 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 使用 方法检查帧是否仍然存在。

    .NET/C# WinRT/C# Win32/C++

    创建框架后,框架将导航到框架的源 URL。 iframe 使用导航和导航事件,例如 FrameNavigationStarting NavigationCompleted 。 当框架导航到源 URL 时,将引发以下导航事件:

  • NavigationStarting
  • ContentLoading
  • HistoryChanged
  • DOMContentLoaded
  • NavigationCompleted
  • 在框架内导航的频率

    导航可能会在框架中发生。 作为一个简单的用例, iframe 元素的 source 属性是一个 URL(如 wikipedia.com ),该 URL 加载到 iframe 中。 通常,导航会在创建框架后立即发生。 ContentLoading 然后引发 、 DOMContentLoaded NavigationCompleted 事件。

    框架本身正在导航。 网页导航到 URL。 同样,帧可能会导航。

    创建框架后,框架将按照主机应用的驱动方式进行导航。 若要监视主页中发生的情况,事件(如 NavigationStarting NavigationCompleted ),并使 HistoryChanged 主机应用能够在框架或网页之间来回导航。 框架导航到新 URL 的频率低于网页,但支持相同的导航样式。 用户通常无法在框架内导航,尽管 JavaScript 支持该操作:框架在导航方面通常是静态的。

    另请参阅:

  • WebView2 应用的导航事件 中的 标准事件序列
  • CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync 方法 - 此方法可用于 iframe 和网页。 脚本必须检查它是否在 iframe 中。
  • 导航事件:

  • CoreWebView2Frame.NavigationStarting 事件
  • CoreWebView2.FrameNavigationStarting 事件 (被取代)
  • CoreWebView2.SourceChanged 事件
  • CoreWebView2Frame.ContentLoading 事件
  • CoreWebView2.HistoryChanged 事件
  • CoreWebView2.BasicAuthenticationRequested 事件
  • CoreWebView2Frame.DOMContentLoaded
  • CoreWebView2Frame.NavigationCompleted 事件
  • CoreWebView2.FrameNavigationCompleted 事件 (取代)
  • CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync 方法 - 此方法可用于 iframe 和网页。 脚本必须检查它是否在 iframe 中。
  • 导航事件:

  • CoreWebView2Frame.NavigationStarting 事件
  • CoreWebView2.FrameNavigationStarting 事件 (被取代)
  • CoreWebView2.SourceChanged 事件
  • CoreWebView2Frame.ContentLoading 事件
  • CoreWebView2.HistoryChanged 事件
  • CoreWebView2.BasicAuthenticationRequested 事件
  • CoreWebView2.DOMContentLoaded 事件
  • CoreWebView2Frame.NavigationCompleted 事件
  • CoreWebView2.FrameNavigationCompleted 事件 (取代)
  • ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler 接口
  • ICoreWebView2::AddScriptToExecuteOnDocumentCreated 方法 - 此方法可用于 iframe 和网页。 脚本必须检查它是否在 iframe 中。
  • 导航事件:

  • ICoreWebView2Frame2::NavigationStarting 事件 (添加 删除)
  • ICoreWebView2::FrameNavigationStarting 事件 (被取代) (添加 删除)
  • ICoreWebView2::SourceChanged 事件 (添加 删除)
  • ICoreWebView2::ContentLoading 事件 (添加 删除)
  • ICoreWebView2Frame2::ContentLoading 事件 (添加 删除)
  • ICoreWebView2::HistoryChanged 事件 (添加 删除)
  • ICoreWebView2_10::BasicAuthenticationRequested 事件 (添加 删除)
  • ICoreWebView2_2::D OMContentLoaded 事件 (添加 删除)
  • ICoreWebView2Frame2::D OMContentLoaded 事件 (添加 删除)
  • ICoreWebView2Frame2::NavigationCompleted 事件 (添加 删除)
  • ICoreWebView2::FrameNavigationCompleted 事件 (取代) (添加 删除)
  • 对于重复的等效 NavigationStarting 项和 NavigationCompleted 事件,建议使用 上的 CoreWebView2Frame 事件,而不是上的 CoreWebView2 等效的取代事件,因为 类型 CoreWebView2Frame 支持更多方案,以允许与帧交互。

    另请参阅:

  • WebView2 应用的导航事件 中的 标准事件序列
  • WebView2 功能和 API 概述 中的 导航事件
  • WebView2 功能和 API 概述 阻止不需要的导航
  • 在 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 参考主题,尽管对于帧,你会改用支持 参数的方法。
  • ICoreWebView2Frame::AddHostObjectToScriptWithOrigins 方法 - 具有 参数 origins 。 文档没有 方法名称 表。
  • 上述方法的工作方式类似于以下方法:

  • ICoreWebView2::AddHostObjectToScript 方法 。 请参阅 方法名称 表。 阅读这两个 origins API 参考主题,尽管对于帧,你会改用支持 参数的方法。
  • 将 Web 消息从 iframe 发送到主机应用

    若要将 Web 消息从 iframe 发送到主机应用,请使用 window.chrome.webview.postMessage 方法:

    window.chrome.webview.postMessage(`SetTitleText ${titleText.value}`);
    

    若要在主机应用中接收这些消息,主机应用必须订阅 WebMessageReceived event

    将消息从主机应用发送到 iframe

    主机应用通过调用 PostWebMessageAsJsonPostWebMessageAsString 方法将消息发送到 iframe。

    iframe 通过订阅 window.chrome.webview.addEventListener('message') 事件来接收消息,如下所示:

    window.chrome.webview.addEventListener('message', arg => {
        // implement event listener here
    
  • ICoreWebView2Frame2::WebMessageReceived 事件 (添加删除)
  • ICoreWebView2Frame2::P ostWebMessageAsJson 方法
  • ICoreWebView2Frame2::P ostWebMessageAsString 方法
  • 使用 ExecuteScript 在 iframe 中运行 JavaScript 代码

    WebView2 应用可以使用 在框架 ExecuteScript中运行任何 JavaScript。

    若要在 iframe 中运行脚本,必须创建执行上下文。 执行上下文是在事件之后 ContentLoading 创建的,因此,如果在 ExecuteScript 引发事件之前 ContentLoading 调用 ,脚本将不会运行,并且将返回字符串 null

    有关事件 ContentLoading 的信息,请参阅 WebView2 应用的导航事件,该事件对框架和网页有效。

    .NET/C# WinRT/C# Win32/C++

    使用 WebResourceRequested iframe 中的 事件修改网络事件

    对于 iframe,可以使用 事件侦听网络事件并对其进行 WebResourceRequested 修改。

    另请参阅:

  • 在 WebView2功能和 API 概述中管理 WebView2 中的网络请求。
  • 网络请求的自定义管理
  • 1.0.1222-prerelease >有关这些 API 的 WebView2 SDK 发行说明中的实验性功能。
  • CoreWebView2.AddWebResourceRequestedFilter (uri、resourceContext、requestSourceKinds) 方法重载 - 若要订阅属于 iframe 的网络请求,必须使用此重载并将 用作 Document 参数的值 requestSourceKinds
  • CoreWebView2WebResourceRequestSourceKinds 枚举
  • CoreWebView2.RemoveWebResourceRequestedFilter (uri、resourceContext、requestSourceKinds) 方法重载
  • CoreWebView2WebResourceRequestedEventArgs 类
  • CoreWebView2.AddWebResourceRequestedFilter (uri、resourceContext、requestSourceKinds) 方法重载 - 若要订阅属于 iframe 的网络请求,必须使用此重载并将 用作 Document 参数的值 requestSourceKinds
  • CoreWebView2WebResourceRequestSourceKinds 枚举
  • CoreWebView2.RemoveWebResourceRequestedFilter (uri、resourceContext、requestSourceKinds) 方法重载
  • CoreWebView2WebResourceRequestedEventArgs 类
  • ICoreWebView2Experimental16.AddWebResourceRequestedFilterWithRequestSourceKinds 方法 - 若要订阅属于 iframe 的网络请求,必须使用此方法 ...WithRequestSourceKinds 并使用 COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_DOCUMENT 作为 参数的值 requestSourceKinds
  • COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS枚举
  • ICoreWebView2Experimental16.RemoveWebResourceRequestedFilterWithRequestSourceKinds 方法
  • ICoreWebView2ExperimentalWebResourceRequestedEventArgs 接口
  • 忽略 X-Frame-Options 以在框架内呈现网页

    X-Frame-Options网页使用 HTTP 响应标头来防止应用程序在框架内呈现该网页。 属性 AdditionalAllowedFrameAncestors 允许应用程序绕过 X-Frame-Options 标头,在框架内呈现网页。

    另请参阅:

  • X-Frame-Options
  • 此示例代码从 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);");
    

    此示例代码是从 ICoreWebView2Frame2::ExecuteScript 方法复制的

    wil::com_ptr<ICoreWebView2_4> webview2_4 = m_webView.try_query<ICoreWebView2_4>();
    if (webview2_4)
        // Subscribe to the FrameCreated event to obtain the frame object when it's created.
        CHECK_FAILURE(webview2_4->add_FrameCreated(
            Callback<ICoreWebView2FrameCreatedEventHandler>(
                [](ICoreWebView2* sender, ICoreWebView2FrameCreatedEventArgs* args) -> HRESULT {
                    wil::com_ptr<ICoreWebView2Frame> webviewFrame;
                    CHECK_FAILURE(args->get_Frame(&webviewFrame));
                    // DOMContentLoaded event was introduced in ICoreWebView2Frame2 interface.
                    // So in order to have access to this interface, query ICoreWebView2Frame2
                    // from ICoreWebView2Frame.
                    wil::com_ptr<ICoreWebView2Frame2> frame2 =
                        webviewFrame.try_query<ICoreWebView2Frame2>();
                    if (frame2)
                            // In order for ExecuteScript to successfully run inside the
                            // iframe, subscribe to the ContentLoading or DOMContentLoaded
                            // event.  Once these events are raised, you can call ExecuteScript.
                            frame2->add_DOMContentLoaded(
                            Callback<ICoreWebView2FrameDOMContentLoadedEventHandler>(
                                [](ICoreWebView2Frame* frame,
                                    ICoreWebView2DOMContentLoadedEventArgs* args) -> HRESULT {
                                    wil::com_ptr<ICoreWebView2Frame2> frame2;
                                    frame->QueryInterface(IID_PPV_ARGS(&frame2));
                                    frame2->ExecuteScript(
                                        LR"~(
                                        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);
                                        Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
                                            [](HRESULT error, PCWSTR result) -> HRESULT {
                                                // Handle ExecuteScript error and result here if needed
                                                // or pass nullptr as callback parameter otherwise.
                                                return S_OK;
                                            .Get());
                                    return S_OK;
                                .Get(),
                            NULL);
                    return S_OK;
                .Get(),
            &m_frameCreatedToken));