Compartir a través de


Interoperabilidad del código nativo y del lado web

El control WebView2 de Microsoft Edge permite insertar contenido web en aplicaciones nativas. Puede usar WebView2 de diferentes maneras, en función de lo que necesite realizar. En este artículo se describe cómo comunicarse mediante mensajes simples, código JavaScript y objetos nativos.

Algunos casos de uso comunes incluyen:

  • Actualice el título de la ventana de host nativa después de navegar a otro sitio web.
  • Enviar un objeto de cámara nativo y usar sus métodos desde una aplicación web.
  • Ejecute un archivo JavaScript dedicado en el lado web de una aplicación.

Antes de empezar

En este tutorial se recorre el código de la aplicación de ejemplo para mostrar algunas de las funcionalidades de comunicación de WebView2. Clone el repositorio WebView2Samples, abra un .sln archivo en Visual Studio, compile el proyecto y ejecute (depurar) para seguir los pasos de este artículo.

Para obtener pasos detallados sobre la clonación del repositorio, consulte Ejemplos de WebView2.

Escenario: Mensajería simple

Los controles WebView2 permiten intercambiar mensajes simples entre los lados web y nativo de una aplicación. Puede usar tipos de datos como JSON o String para enviar mensajes entre la aplicación host y WebView2.

Envío de mensajes desde la aplicación host a WebView2

En este ejemplo se muestra cómo la aplicación de ejemplo cambia el color del texto en el front-end, en función de un mensaje de la aplicación host.

Para ver la mensajería en acción:

  1. Ejecute la aplicación de ejemplo, seleccione la pestaña Escenario y seleccione la opción Mensajería web .

    Aparece la siguiente pantalla:

    Página de ejemplo de mensajería web, que muestra la interacción básica entre la aplicación host y la instancia de WebView2 mediante mensajes web

  2. Observe la primera sección, titulada Posting Messages. Siga las instrucciones y seleccione ScriptPost Message JSON (Script> Post Message JSON). Después, haga clic en Aceptar. El mensaje se vuelve azul:

    Demostración de

    ¿Cómo hemos podido cambiar el color del texto? El ejemplo comienza creando un botón en el lado nativo. A continuación, el ejemplo agrega el código siguiente para publicar el mensaje web cuando se hace clic en el botón. Este código cambia el color del texto web a azul.

    En el ejemplo se incluye código de C++ para crear un botón de Windows que llama SendJsonWebMessage() al hacer clic en él.

    Para obtener más información sobre cómo crear un botón en C++, vea Cómo crear un botón.

  3. Cuando se hace clic en el botón, llama al código siguiente desde ScriptComponent.cpp.

    // Prompt the user for some JSON and then post it as a web message.
    void ScriptComponent::SendJsonWebMessage()
    {
        TextInputDialog dialog(
            m_appWindow->GetMainWindow(),
            L"Post Web Message JSON",
            L"Web message JSON:",
            L"Enter the web message as JSON.",
            L"{\"SetColor\":\"blue\"}");
        if (dialog.confirmed)
        {
            m_webView->PostWebMessageAsJson(dialog.input.c_str());
        }
    }
    

    Nota:

    En el resto de este tutorial se usa el archivo del ejemplo ScenarioWebMessage.html WebView2. Compare su propio archivo HTML mientras trabaja, o copie y pegue el contenido de ScenarioWebMessage.html.

    En el ejemplo se usa un agente de escucha de eventos de JavaScript en la web.

  4. ScenarioWebMessage.html incluye el siguiente Código JavaScript en el encabezado:

    window.chrome.webview.addEventListener('message', arg => {
       if ("SetColor" in arg.data) {
          document.getElementById("colorable").style.color = 
          arg.data.SetColor;
       }
    });
    

    El agente de escucha de eventos escucha un evento de mensaje y hace que el texto del mensaje sea coloreable.

  5. El archivo HTML describe el ejercicio de mensajería:

    <h1>WebMessage sample page</h1>
    <p>This page demonstrates basic interaction between the host app 
    and the webview by means of Web Messages.</p>
    
    <h2>Posting Messages</h2>
    <p id="colorable">Messages can be posted from the host app to the 
    webview using the functions
    <code>ICoreWebView2::PostWebMessageAsJson</code> and
    <code>ICoreWebView2::PostWebMessageAsString</code>. Try selecting 
    the menu item "Script > Post Message JSON" to send the message 
    <code>{"SetColor":"blue"}</code>.
    It should change the text color of this paragraph.</p>
    
  6. El Post Message JSON elemento de menú se encuentra en el archivo de script de recursos generado Microsoft Visual C++ WebView2APISample.rc.

    MENUITEM "Post Message JSON",           IDM_POST_WEB_MESSAGE_JSON
    
  7. El archivo de script, a su vez, llama al caso IDM_POST_WEB_MESSAGE_JSON en ScriptComponent.cpp.

    case IDM_POST_WEB_MESSAGE_JSON:
       SendJsonWebMessage();
       return true;
    

Esto completa el ejemplo que muestra cómo WebView2 se comunica a través de mensajes simples.

Recibir cadenas de mensaje a través de postMessage

Este ejemplo sigue la Receiving Messages sección de la página web para cambiar el texto de la barra de título. La aplicación host recibe un mensaje de WebView2 con el nuevo texto de la barra de título.

El archivo de C++ controla el texto del título y lo comunica a la aplicación host como una cadena.

  1. Cuando se hace clic en el botón, WebView2 transmite un mensaje de la página web a la aplicación nativa mediante window.chrome.webview.postMessage en ScenarioWebMessage.html.

    function SetTitleText() {
       let titleText = document.getElementById("title-text");
       window.chrome.webview.postMessage(`SetTitleText ${titleText.value}`);
    }
    
  2. El archivo HTML incluye un cuadro de texto y un botón para enviar un mensaje a la aplicación host:

    <h2>Receiving Messages</h2>
    <p>The host app can receive messages by registering an event handler 
    with <code>ICoreWebView2::add_WebMessageReceived</code>. If you 
    enter text and click "Send", this page will send a message to the 
    host app which will change the text of the title bar.</p>
    <input type="text" id="title-text"/>
    <button onclick="SetTitleText()">Send</button>
    
  3. El controlador de eventos de ScenarioWebMessage.cpp procesa la nueva cadena de texto de título y la comunica a la aplicación host como una cadena.

    // Setup the web message received event handler before navigating to
    // ensure we don't miss any messages.
    CHECK_FAILURE(m_webView->add_WebMessageReceived(
       Microsoft::WRL::Callback<ICoreWebView2WebMessageReceivedEventHandler>(
          [this](ICoreWebView2* sender, ICoreWebView2WebMessageReceivedEventArgs* args)
    {
       wil::unique_cotaskmem_string uri;
       CHECK_FAILURE(args->get_Source(&uri));
    
       // Always validate that the origin of the message is what you expect.
       if (uri.get() != m_sampleUri)
       {
          return S_OK;
       }
       wil::unique_cotaskmem_string messageRaw;
       CHECK_FAILURE(args->TryGetWebMessageAsString(&messageRaw));
       std::wstring message = messageRaw.get();
    
       if (message.compare(0, 13, L"SetTitleText ") == 0)
       {
          m_appWindow->SetTitleText(message.substr(13).c_str());
       }
       else if (message.compare(L"GetWindowBounds") == 0)
       {
          RECT bounds = m_appWindow->GetWindowBounds();
          std::wstring reply =
                L"{\"WindowBounds\":\"Left:" + std::to_wstring(bounds.left)
                + L"\\nTop:" + std::to_wstring(bounds.top)
                + L"\\nRight:" + std::to_wstring(bounds.right)
                + L"\\nBottom:" + std::to_wstring(bounds.bottom)
                + L"\"}";
          CHECK_FAILURE(sender->PostWebMessageAsJson(reply.c_str()));
       }
       return S_OK;
    }).Get(), &m_webMessageReceivedToken));
    

Mensajes de ida y vuelta

En este ejemplo se sigue la <h2>Round trip</h2> sección de la página de ejemplo WebMessage, ScenarioWebMessage.html. En este ejemplo se muestra un mensaje de ida y vuelta desde WebView2 a la aplicación host y de vuelta. La aplicación host recibe una solicitud de WebView2 y devuelve los límites de la ventana activa.

Cuando lo solicita la aplicación host, el archivo de C++ obtiene los límites de ventana y envía los datos a WebView2 como un mensaje web JSON.

  1. El archivo HTML incluye un botón para obtener los límites de ventana de la aplicación host:

    <h2>Round trip</h2>
    <p>The host app can send messages back in response to received 
    messages. If you click the <b>Get window bounds</b> button, the 
    host app reports back the bounds of its window, which are 
    displayed in the text box.</p>
    <button onclick="GetWindowBounds()">Get window bounds</button><br>
    <textarea id="window-bounds" rows="4" readonly></textarea>
    
  2. Cuando el usuario hace clic en el botón, WebView2 transmite un mensaje de la página web a la aplicación nativa mediante window.chrome.webview.postMessage.

    function GetWindowBounds() {
       window.chrome.webview.postMessage("GetWindowBounds");
    }
    
  3. El controlador de eventos de ScenarioWebMessage.cpp obtiene los límites de ventana y envía los datos a la aplicación host mediante TryGetWebMessageAsString:

    // Setup the web message received event handler before navigating to
    // ensure we don't miss any messages.
    CHECK_FAILURE(m_webView->add_WebMessageReceived(
       Microsoft::WRL::Callback<ICoreWebView2WebMessageReceivedEventHandler>(
          [this](ICoreWebView2* sender, ICoreWebView2WebMessageReceivedEventArgs* args)
    {
       wil::unique_cotaskmem_string uri;
       CHECK_FAILURE(args->get_Source(&uri));
    
       // Always validate that the origin of the message is what you expect.
       if (uri.get() != m_sampleUri)
       {
          return S_OK;
       }
       wil::unique_cotaskmem_string messageRaw;
       CHECK_FAILURE(args->TryGetWebMessageAsString(&messageRaw));
       std::wstring message = messageRaw.get();
    
       if (message.compare(0, 13, L"SetTitleText ") == 0)
       {
          m_appWindow->SetTitleText(message.substr(13).c_str());
       }
       else if (message.compare(L"GetWindowBounds") == 0)
       {
          RECT bounds = m_appWindow->GetWindowBounds();
          std::wstring reply =
                L"{\"WindowBounds\":\"Left:" + std::to_wstring(bounds.left)
                + L"\\nTop:" + std::to_wstring(bounds.top)
                + L"\\nRight:" + std::to_wstring(bounds.right)
                + L"\\nBottom:" + std::to_wstring(bounds.bottom)
                + L"\"}";
          CHECK_FAILURE(sender->PostWebMessageAsJson(reply.c_str()));
       }
       return S_OK;
    }).Get(), &m_webMessageReceivedToken));
    

    Los límites de ventana se muestran en la página web.

Escenario: Envío de código JavaScript

En este escenario se muestra cómo ejecutar JavaScript en la web. En este enfoque, la aplicación host especifica el código JavaScript que se va a ejecutar y pasa el código a la web a través de ExecuteScriptAsync. La ExecuteScriptAsync función devuelve el resultado de JavaScript al autor de la ExecuteScript llamada.

Para obtener más información, consulte Uso de JavaScript en WebView2 (ejecutar JavaScript desde código nativo).

Escenario: Envío de objetos nativos

Pase el objeto nativo a la web. A continuación, llame a los métodos del objeto desde la web.

Para usar mensajes que representan llamadas de método, use la AddHostObjectToScript API. En un nivel alto, esta API le permite exponer objetos nativos (host) en el lado web y actuar como proxy. Obtenga acceso a estos objetos mediante window.chrome.webview.hostObjects.{name}.

Pasar un objeto nativo al lado web de una aplicación se describe en la sección AddHostObjectToScript de la interfaz ICoreWebView2.

¡Enhorabuena! Ha insertado correctamente contenido web en aplicaciones nativas.

Vea también