Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O WebView2 permite que os aplicativos façam a ponte entre a Web e os lados nativos de um aplicativo, permitindo que um objeto seja passado para a Web. Você expõe APIs selecionadas do lado nativo ao JavaScript da página da Web por meio de um objeto host nativo intermediário definido no código nativo. As APIs do lado nativo são projetadas em JavaScript usando a API WebView2 AddHostObjectToScript .
Este artigo aborda principalmente o Win32/C++ e também aborda alguns aspectos do .NET/C# dentro de quadros. Para o WinRT, consulte Chamar o código WinRT do lado nativo a partir do código do lado da Web.
Por que usar AddHostObjectToScript?
Ao desenvolver um aplicativo WebView2, você pode encontrar um objeto nativo cujos métodos ou propriedades você considera úteis. Talvez você queira disparar esses métodos de objeto nativos do código do lado da Web, como resultado da interação do usuário no lado da Web do seu aplicativo. Além disso, talvez você não queira implementar novamente os métodos de seus objetos nativos em seu código do lado da Web. A
AddHostObjectToScriptAPI permite a reutilização do código do lado nativo pelo código do lado da Web.Por exemplo, pode haver uma API de webcam nativa, o que exigiria a reescrita de uma grande quantidade de código no lado da Web. Ter a capacidade de chamar os métodos do objeto nativo é mais rápido e eficiente do que recodificar os métodos do objeto no lado da Web do seu aplicativo. Nesse caso, seu código do lado nativo pode passar o objeto para o código JavaScript do lado da Web do seu aplicativo, para que seu código JavaScript possa reutilizar os métodos da API nativa.
Cenários que podem se beneficiar do uso de objetos host no script:
Há uma API de teclado e você deseja chamar a
keyboardObject.showKeyboardfunção do lado da Web.Acessar o sistema de arquivos, não apenas a sandbox da página da web, via JavaScript. O JavaScript está na área restrita, o que o impede de acessar diretamente o sistema de arquivos. Ao usar
AddHostObjectToScriptpara criar um objeto nativo exposto a JavaScript, você pode usar o objeto host para manipular arquivos no sistema de arquivos, não apenas na área restrita da página da Web.
Este artigo usa o aplicativo de exemplo Win32 para demonstrar algumas aplicações práticas do AddHostObjectToScript.
Etapa 1: Instale o Visual Studio, instale o git, clone o repositório WebView2Samples e abra a solução
Baixe e instale o Microsoft Visual Studio 2019 (versão 16.11.10) ou posterior e outros pré-requisitos, conforme descrito no aplicativo de exemplo Win32. O aplicativo de exemplo Win32 foi criado usando o Visual Studio 2019, portanto, para seguir as etapas de exemplo neste artigo, recomendamos começar com o Visual Studio 2019 em vez do Visual Studio 2022.
Clone o repositório WebView2Samples . O repositório inclui o aplicativo de exemplo WebView2 específico do Win32. Para obter instruções, em uma nova janela ou guia, consulte Aplicativo de exemplo Win32.
Abra o Microsoft Visual Studio. Recomendamos abrir inicialmente o exemplo Win32 usando o Visual Studio 2019.
Na cópia local do repositório clonado
WebView2Samples, abraSampleApps>WebView2Samples>WebView2Samples.sln.WebView2Samples.slninclui oWebView2APISampleprojeto, que é o aplicativo de exemplo Win32. Mantenha a solução de aplicativo de exemplo aberta para acompanhar o restante deste artigo.
Etapa 2: Definir a interface COM do objeto host usando a IDL
Defina a interface COM do objeto host em um .idl arquivo, como HostObjectSample.idl, para descrever os métodos e as propriedades no objeto host.
Primeiro, use a IDL (linguagem de definição de interface) para definir a interface COM do objeto host. Essa definição de objeto host em um idl arquivo descreve as propriedades e os métodos do lado nativo expostos (ou "encapsulados"). O arquivo IDL (.idl) define uma interface, mas não a implementa.
No Visual Studio Gerenciador de Soluções, expanda WebView2APISample>Source Files e clique
HostObjectSample.idlduas vezes para abri-lo.O código a seguir define a
IHostObjectSampleinterface, que herdaIUnknowncomo é padrão para COM. Use essaIHostObjectSampledefinição como um modelo para definir os métodos, propriedades, funções de retorno de chamada do objeto e assim por diante.import "oaidl.idl"; import "ocidl.idl"; [uuid(0a7a4655-5660-47d0-8a37-98ae21399e57), version(0.1)] library HostObjectSampleLibrary { [uuid(3a14c9c0-bc3e-453f-a314-4ce4a0ec81d8), object, local] interface IHostObjectSample : IUnknown { // Demonstrates a basic method call with some parameters and a return value. HRESULT MethodWithParametersAndReturnValue([in] BSTR stringParameter, [in] INT integerParameter, [out, retval] BSTR* stringResult); // Demonstrate getting and setting a property. [propget] HRESULT Property([out, retval] BSTR* stringResult); [propput] HRESULT Property([in] BSTR stringValue); [propget] HRESULT IndexedProperty(INT index, [out, retval] BSTR * stringResult); [propput] HRESULT IndexedProperty(INT index, [in] BSTR stringValue); // Demonstrate native calling back into JavaScript. HRESULT CallCallbackAsynchronously([in] IDispatch* callbackParameter); // Demonstrates a property which uses Date types. [propget] HRESULT DateProperty([out, retval] DATE * dateResult); [propput] HRESULT DateProperty([in] DATE dateValue); // Creates a date object on the native side and sets the DateProperty to it. HRESULT CreateNativeDate(); };Acima, observe o
DateProperty, que usa umDATEtipo. Vamos nos concentrar nessa propriedade de demonstração de data neste artigo.
Etapa 3: Definir uma coclasse de objeto host
Em seguida, o exemplo define a HostObjectSample coclasse a ser incluída IHostObjectSample e IDispatch.
Em
HostObjectSample.idl, examine a coclasse (classe deHostObjectSampleobjeto componente), que inclui asIHostObjectSampleinterfaces eIDispatch:[uuid(637abc45-11f7-4dde-84b4-317d62a638d3)] coclass HostObjectSample { [default] interface IHostObjectSample; interface IDispatch; }; }A
HostObjectSamplecoclasse incluiinterface IDispatch, que é necessária para que o objeto host funcione comAddHostObjectToScript.
Etapa 4: Implementar os membros do objeto C++
No código do aplicativo de exemplo Win32, HostObjectSampleImpl.cpp usa o esqueleto criado no arquivo IDL COM e implementa cada membro do objeto C++. Este arquivo C++ (.cpp) implementa a interface definida (e também implementa IDispatch).
Implemente todas as funções definidas na interface do objeto, conforme descrito no arquivo IDL. Certifique-se de implementar as funções exigidas pelo IDispatch. O compilador lançará um erro se essas funções não estiverem definidas.
Em seguida, examinamos duas propriedades específicas que foram definidas na IDL, para mostrar como a IDL está relacionada ao .cpp arquivo.
No Visual Studio Gerenciador de Soluções, expanda WebView2APISample>Source Files e clique duas vezes em HostObjectSampleImpl.cpp para abri-lo.
Examine as declarações de propriedade em HostObjectSample.idl:
// Demonstrate getting and setting a property. [propget] HRESULT Property([out, retval] BSTR* stringResult); [propput] HRESULT Property([in] BSTR stringValue); ... // Demonstrate a property which uses Date types [propget] HRESULT DateProperty([out, retval] DATE * dateResult); [propput] HRESULT DateProperty([in] DATE dateValue); // Creates a date object on the native side and sets the DateProperty to it. HRESULT CreateNativeDate();Examine a implementação das propriedades do objeto em HostObjectSampleImpl.cpp:
STDMETHODIMP HostObjectSample::get_Property(BSTR* stringResult) { *stringResult = SysAllocString(m_propertyValue.c_str()); return S_OK; } STDMETHODIMP HostObjectSample::put_Property(BSTR stringValue) { m_propertyValue = stringValue; return S_OK; } ... STDMETHODIMP HostObjectSample::get_DateProperty(DATE* dateResult) { *dateResult = m_date; return S_OK; } STDMETHODIMP HostObjectSample::put_DateProperty(DATE dateValue) { m_date = dateValue; SYSTEMTIME systemTime; if (VariantTimeToSystemTime(dateValue, &systemTime)) ... } STDMETHODIMP HostObjectSample::CreateNativeDate() { SYSTEMTIME systemTime; GetSystemTime(&systemTime); DATE date; if (SystemTimeToVariantTime(&systemTime, &date)) { return put_DateProperty(date); } return E_UNEXPECTED; }Examine
DateProperty, que rastreamos ao longo deste artigo.
Etapa 5: Implementar IDispatch
O objeto host deve implementar IDispatch para que o WebView2 possa projetar o objeto host nativo no código do lado da Web do aplicativo.
IDispatch permite chamar dinamicamente métodos e propriedades. Normalmente, chamar objetos requer invocações estáticas, mas você pode usar JavaScript para criar chamadas de objeto dinamicamente. No código do aplicativo de exemplo Win32, HostObjectSampleImpl.cpp implementa IDispatch, o que significa implementar estes métodos:
GetIDsOfNamesGetTypeInfoGetTypeInfoCountInvoke
Implemente IDispatch conforme descrito em Bibliotecas de tipos e a Linguagem de descrição de objeto. Para obter mais informações sobre IDispatch herança e métodos, consulte Interface IDispatch (oaidl.h).
Se o objeto que você deseja adicionar ao JavaScript ainda não implementar IDispatch, você precisará escrever um IDispatch wrapper de classe para o objeto que deseja expor.
Pode haver bibliotecas para fazer isso automaticamente. Para saber mais sobre as etapas necessárias para escrever um IDispatch wrapper de classe para o objeto que você deseja expor, consulte Automação.
Em seguida, salve todas as alterações feitas no projeto.
No Gerenciador de Soluções, clique com o botão direito do mouse em WebView2APISample (que é o aplicativo de exemplo Win32) e selecione Compilar. Isso cria um arquivo de biblioteca
.tlbde tipos COM. Você precisa fazer referência ao.tlbarquivo a partir do código-fonte C++. Para obter mais informações, consulte Biblioteca de tipos em COM, DCOM e bibliotecas de tipos.
Etapa 6: Chamar AddHostObjectToScript para passar o objeto host para o código do lado da Web
Até agora, construímos nossa interface e implementamos nosso objeto host nativo. Agora estamos prontos para passar AddHostObjectToScript o objeto host nativo para o código JavaScript do lado da Web do nosso aplicativo. O aplicativo de exemplo Win32 chama AddHostObjectToScriptScenarioAddHostObject.cpp, conforme mostrado abaixo.
No Visual Studio Gerenciador de Soluções, abra WebView2APISample>Source Files>ScenarioAddHostObject.cpp.
Vá para a implementação da
ScenarioAddHostObjectclasse. Essa classe exibe HTML e lida com a navegação:ScenarioAddHostObject::ScenarioAddHostObject(AppWindow* appWindow) : m_appWindow(appWindow), m_webView(appWindow->GetWebView()) { std::wstring sampleUri = m_appWindow->GetLocalUri(L"ScenarioAddHostObject.html"); m_hostObject = Microsoft::WRL::Make<HostObjectSample>( [appWindow = m_appWindow](std::function<void(void)> callback) { appWindow->RunAsync(callback); });A
Makeinstrução mostra como instanciar oHostObjectSampleobjeto COM que foi definido no arquivo IDL. Este é o objeto que usaremos mais tarde quando chamarmosAddHostObjectToScript. AMakeinstrução nos dá um ponteiro para a interface implementada no HostObjectSampleImpl.cpp.Em seguida, adicionamos um manipulador de eventos para escutar o
NavigationStartingevento:CHECK_FAILURE(m_webView->add_NavigationStarting( Microsoft::WRL::Callback<ICoreWebView2NavigationStartingEventHandler>( [this, sampleUri](ICoreWebView2* sender, ICoreWebView2NavigationStartingEventArgs* args) -> HRESULT { wil::unique_cotaskmem_string navigationTargetUri; CHECK_FAILURE(args->get_Uri(&navigationTargetUri)); std::wstring uriTarget(navigationTargetUri.get());NavigationStartingNo manipulador de eventos, aquery_tolinha (abaixo) converte o objeto COM recém-criado em umIDispatchtipo e, em seguida, converte o objeto em umVARIANT.VARIANTpermitem que você use estruturas de dados, como inteiros e matrizes, bem como tipos mais complexos, comoIDispatch.Para obter uma lista completa dos tipos de dados com suporte, consulte Estrutura VARIANT (oaidl.h). Nem todos os tipos na união são compatíveis com
AddHostObjectToScript.VARIANTPara obter detalhes, consulte o método ICoreWebView2::AddHostObjectToScript.if (AreFileUrisEqual(sampleUri, uriTarget)) { VARIANT remoteObjectAsVariant = {}; m_hostObject.query_to<IDispatch>(&remoteObjectAsVariant.pdispVal); remoteObjectAsVariant.vt = VT_DISPATCH;Agora que temos uma variante do objeto que é compatível com o código C++, o código do lado nativo do aplicativo de exemplo está pronto para passar o objeto host para o código do lado da Web do aplicativo.
Na linha inferior acima, o
NavigationStartingmanipulador de eventos define o tipo de variante do objeto remoto comoIDispatch.// We can call AddHostObjectToScript multiple times in a row without // calling RemoveHostObject first. This will replace the previous object // with the new object. In our case this is the same object and everything // is fine. CHECK_FAILURE( m_webView->AddHostObjectToScript(L"sample", &remoteObjectAsVariant)); remoteObjectAsVariant.pdispVal->Release(); }Acima, no manipulador de
NavigationStartingeventos, oVARIANTé passado paraAddHostObjectToScript, usando o nomesample.
Etapa 7: Acessar membros do objeto host a partir do JavaScript da página da Web
Nas etapas acima, o código do lado nativo do aplicativo de exemplo criou um objeto host que implementa IDispatch. Esse código nativo também chama a API ICoreWebView2::AddHostObjectToScript WebView2 ou ICoreWebView2Frame::AddHostObjectToScriptWithOrigins e passa o objeto host para o código do lado da Web do aplicativo.
Agora, o código do lado da Web do aplicativo pode acessar as APIs do lado nativo que são expostas pelo objeto host. As instruções JavaScript em seu .html elemento de página da Web script ou em um arquivo JavaScript referenciado .js podem acessar as APIs do lado nativo exportadas.
O código do lado da Web do aplicativo de exemplo Win32 agora é capaz de acessar as propriedades e os métodos do objeto host nativo, para acessar as APIs nativas. Usaremos os controles de página da Web do aplicativo de exemplo, na página da WebObjetos de Host de Cenário> do aplicativo, para demonstrar isso.
No Microsoft Visual Studio, selecioneSalvar Tudo em Arquivo> (Ctrl+Shift+S) para salvar o projeto.
No Gerenciador de Soluções, abra WebView2APISample>ScenarioAddHostObject.html. Compararemos esse arquivo com a página da Web correspondente no aplicativo de exemplo Win32 em execução.
No Gerenciador de Soluções, clique com o botão direito do mouse em WebView2APISample (que é o aplicativo de exemplo Win32) e selecione Compilar.
Pressione F5 para executar o projeto no modo de depuração.
No aplicativo de exemplo Win32 (que tem a barra de título de WebView2APISample), clique no menu Cenário e selecione o item de menu Objetos Host . A página da Web de exemplo AddHostObjectToScript é exibida, definida por
ScenarioAddHostObject.html:
A página da Web sugere o uso da ferramenta Console do DevTools para executar instruções JavaScript no
chrome.webview.hostObjects.sampleobjeto. Se você quiser abrir o DevTools no aplicativo de exemplo, clique com o botão direito do mouse na página e selecione Inspecionar. Em seguida, selecione a guia Console . Para obter mais informações, consulte Visão geral do console.Para abrir o DevTools, pressionar F12 pode não funcionar nesse contexto e pode disparar uma exceção. Nesse caso, no Visual Studio, selecione Parar Depuração e pressione F5 para reiniciar a depuração. No aplicativo de exemplo, selecioneObjetos Hostde Cenário> novamente. Para obter mais informações, consulte Abrir DevTools usando uma abordagem diferente de F12 em Depurar aplicativos WebView2 com o Visual Studio.
A parte inferior da página de demonstração de Objetos Host duplica os membros do objeto de demonstração em um
<iframe>:
Na página de demonstração renderizada no aplicativo de exemplo, leia o texto do rótulo explicando os botões Data .
Clique nos botões Data . Uma cadeia de caracteres de data é exibida abaixo dos botões, como:
sample.dateProperty: Tue Nov 01 2022 12:45:25 GMT-0700 (Pacific Daylight Time)Explore propriedades e métodos clicando nos botões na página da Web de demonstração e inserindo valores para ver como o código de exemplo se comporta. Os botões demonstram o acesso às propriedades e métodos do objeto host a partir do código do lado da Web do aplicativo.
Para obter informações sobre o que está acontecendo no JavaScript, examine o seguinte código em ScenarioAddHostObject.html.
O código a seguir é uma propriedade demo
Date, diretamente dentro dobodyelemento:<h2>Date Objects</h2> <button id="setDateButton">Set Date to Now</button> <label for="setDateButton">Sets <code>chrome.webview.hostObjects.options.shouldSerializeDates = true</code> and then runs <code>chrome.webview.hostObjects.sample.dateProperty = new Date()</code></label> <br /> <button id="createRemoteDateButton">Set Remote Date</button> <label for="createRemoteDateButton">Calls <code>chrome.webview.hostObjects.sample.createNativeDate()</code> to have the native object create and set the current time to the DateProperty</label> <code><pre><span id="dateOutput"></span></pre></code> <div id="div_iframe" style="display: none;"> <h2>IFrame</h2> </div>Você também pode ler o texto do rótulo acima na página de demonstração renderizada no aplicativo de exemplo, explicando o código do botão Data .
O código a seguir é uma propriedade de demonstração
Dateque é encapsulada em umiframeelemento criado dentro de umscriptelemento:// Date property document.getElementById("setDateButton").addEventListener("click", () => { chrome.webview.hostObjects.options.shouldSerializeDates = true; chrome.webview.hostObjects.sync.sample.dateProperty = new Date(); document.getElementById("dateOutput").textContent = "sample.dateProperty: " + chrome.webview.hostObjects.sync.sample.dateProperty; }); document.getElementById("createRemoteDateButton").addEventListener("click", () => { chrome.webview.hostObjects.sync.sample.createNativeDate(); document.getElementById("dateOutput").textContent = "sample.dateProperty: " + chrome.webview.hostObjects.sync.sample.dateProperty; });A expressão
chrome.webview.hostObjects.sync.sample.datePropertyé adatePropertydo objeto host nativo..idlNo arquivo HostObjectSample.idl, descrito anteriormente, a propriedade date é definida como parte do objeto host.
Usando o aplicativo de exemplo
Você pode experimentar usar e modificar o aplicativo de exemplo Win32. Em seguida, siga o mesmo padrão em seu aplicativo:
- Crie um objeto host no código do lado nativo do seu aplicativo.
- Passe o objeto host para o código do lado da Web do seu aplicativo.
- Use o objeto host do código do lado da Web do aplicativo.
Para descobrir quais outras APIs existem no ecossistema de objetos host, consulte WebView2 Win32 C++ ICoreWebView2.
Visão geral de referência de API
Consulte Compartilhamento de objetos host/web em Visão geral das APIs WebView2.
Confira também
- Interoperabilidade web/nativa na Visão geral das APIs WebView2.
- Usando quadros em aplicativos WebView2
- Chamar o código WinRT do lado nativo a partir do código do lado da Web
GitHub: