WebView

A .NET MAUI (.NET Multi-Platform App UI) WebView exibe páginas da Web remotas, arquivos HTML locais e cadeias de caracteres HTML, em um aplicativo. O conteúdo exibido por uma WebView inclui suporte para CSS (folhas de estilos em cascata) e JavaScript. Por padrão, os projetos do .NET MAUI incluem as permissões de plataforma necessárias para que uma WebView exiba uma página da Web remota.

WebView define as propriedades a seguir:

  • Cookies, do tipo CookieContainer, fornece armazenamento para uma coleção de cookies.
  • CanGoBack, do tipo bool, indica se o usuário pode navegar para páginas anteriores. Trata-se de uma propriedade somente leitura.
  • CanGoForward, do tipo bool, indica se o usuário pode navegar para frente. Trata-se de uma propriedade somente leitura.
  • Source, do tipo WebViewSource, representa o local exibido por WebView.
  • UserAgent, do tipo string, representa o agente do usuário. O valor padrão é o agente do usuário do navegador da plataforma subjacente ou null se ele não pode ser determinado.

Essas propriedades são apoiadas por objetos BindableProperty, o que significa que podem ser alvos de associações de dados e ser estilizada.

A propriedade Source pode ser definida como um objeto UrlWebViewSource ou um objeto HtmlWebViewSource, ambos derivados de WebViewSource. Um UrlWebViewSource é usado para carregar uma página da Web especificada com uma URL, enquanto um objeto HtmlWebViewSource é usado para carregar um arquivo HTML local ou HTML local.

WebView define um evento Navigating gerado quando a navegação de página é iniciada e um evento Navigated gerado quando a navegação da página é concluída. O objeto WebNavigatingEventArgs que acompanha o evento Navigating define uma propriedade Cancel do tipo bool que pode ser usada para cancelar a navegação. O objeto WebNavigatedEventArgs que acompanha o evento Navigated define uma propriedade Result do tipo WebNavigationResult que indica o resultado da navegação.

WebView define os seguintes eventos:

  • Navigating, que é gerado quando a navegação de página começa. O objeto WebNavigatingEventArgs que acompanha esse evento define uma propriedade Cancel do tipo bool que pode ser usada para cancelar a navegação.
  • Navigated, que é gerado quando a navegação de página é concluída. O objeto WebNavigatedEventArgs que acompanha esse evento define uma propriedade Result do tipo WebNavigationResult que indica o resultado da navegação.
  • ProcessTerminated, que é gerado quando um processo WebView termina inesperadamente. O objeto WebViewProcessTerminatedEventArgs que acompanha esse evento define propriedades específicas da plataforma que indicam por que o processo falhou.

Importante

Um WebView precisa especificar as próprias propriedades HeightRequest e WidthRequest quando contido em um HorizontalStackLayout, StackLayout ou VerticalStackLayout. Se você não especificar essas propriedades, o WebView não será renderizado.

Exibir uma página da Web

Para exibir uma página da Web remota, defina a propriedade Source como um string que especifica o URI:

<WebView Source="https://video2.skills-academy.com/dotnet/maui" />

Este é o código C# equivalente:

WebView webvView = new WebView
{
    Source = "https://video2.skills-academy.com/dotnet/maui"
};

Os URIs precisam ser totalmente formados com o protocolo especificado.

Observação

Apesar da propriedade Source ser do tipo WebViewSource, a propriedade pode ser definida como um URI baseado em cadeia de caracteres. Isso ocorre porque o .NET MAUI inclui um conversor de tipo e um operador de conversão implícita, que converte o URI baseado em cadeia de caracteres em um objeto UrlWebViewSource.

Configurar a Segurança do Transporte do Aplicativo no iOS e no Mac Catalyst

Da versão 9 em diante, o iOS só permitirá que seu aplicativo se comunique com servidores seguros. Um aplicativo precisa optar por habilitar a comunicação com servidores não seguros.

A seguinte configuração de Info.plist mostra como habilitar um domínio específico para ignorar os requisitos de ATS (Segurança de Transporte da Apple):

	<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSExceptionDomains</key>
		<dict>
			<key>mydomain.com</key>
			<dict>
				<key>NSIncludesSubdomains</key>
				<true/>
				<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
				<true/>
				<key>NSTemporaryExceptionMinimumTLSVersion</key>
				<string>TLSv1.1</string>
			</dict>
		</dict>
	</dict>

É uma prática recomendada habilitar apenas domínios específicos para ignorar o ATS, permitindo que você use sites confiáveis enquanto se beneficia de segurança adicional em domínios não confiáveis.

A seguinte configuração de Info.plist mostra como desabilitar o ATS para um aplicativo:

	<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSAllowsArbitraryLoads</key>
		<true/>
	</dict>

Importante

Se o aplicativo exigir uma conexão com um site não seguro, você sempre deverá inserir o domínio como uma exceção usando a chave NSExceptionDomains em vez de desativar completamente o ATS usando a chave NSAllowsArbitraryLoads.

Exibir HTML local

Para exibir HTML embutido, defina a propriedade Source como um objeto HtmlWebViewSource:

<WebView>
    <WebView.Source>
        <HtmlWebViewSource Html="&lt;HTML&gt;&lt;BODY&gt;&lt;H1&gt;.NET MAUI&lt;/H1&gt;&lt;P&gt;Welcome to WebView.&lt;/P&gt;&lt;/BODY&gt;&lt;HTML&gt;" />
    </WebView.Source>
</WebView>

No XAML, as cadeias de caracteres HTML podem se tornar ilegíveis devido ao escape dos símbolos < e >. Como alternativa, para maior legibilidade, o HTML pode ser embutido em uma seção CDATA:

<WebView>
    <WebView.Source>
        <HtmlWebViewSource>
            <HtmlWebViewSource.Html>
                <![CDATA[
                <HTML>
                <BODY>
                <H1>.NET MAUI</H1>
                <P>Welcome to WebView.</P>
                </BODY>
                </HTML>
                ]]>
            </HtmlWebViewSource.Html>
        </HtmlWebViewSource>
    </WebView.Source>
</WebView>

Este é o código C# equivalente:

WebView webView = new WebView
{
    Source = new HtmlWebViewSource
    {
        Html = @"<HTML><BODY><H1>.NET MAUI</H1><P>Welcome to WebView.</P></BODY></HTML>"
    }
};

Exibir um arquivo HTML local

Para exibir um arquivo HTML local, adicione o arquivo à pasta Resources\Raw do projeto do aplicativo e defina a ação de build dela como MauiAsset. Em seguida, o arquivo pode ser carregado do HTML embutido definido em um objeto HtmlWebViewSource definido como o valor da propriedade Source:

<WebView>
    <WebView.Source>
        <HtmlWebViewSource>
            <HtmlWebViewSource.Html>
                <![CDATA[
                <html>
                <head>
                </head>
                <body>
                <h1>.NET MAUI</h1>
                <p>The CSS and image are loaded from local files!</p>
                <p><a href="localfile.html">next page</a></p>
                </body>
                </html>                    
                ]]>
            </HtmlWebViewSource.Html>
        </HtmlWebViewSource>
    </WebView.Source>
</WebView>

O arquivo HTML local poderá carregar CSS (Folhas de Estilos em Cascata), JavaScript e imagens, se eles também tiverem sido adicionados ao seu projeto de aplicativo com a ação de build MauiAsset.

Para obter mais informações sobre ativos brutos, confira Ativos brutos.

Recarregar conteúdo

WebView tem um método Reload que pode ser chamado para recarregar sua origem:

WebView webView = new WebView();
...
webView.Reload();

Quando o método Reload é chamado, o evento ReloadRequested é acionado, indicando que uma solicitação foi feita para recarregar o conteúdo atual.

Realizar navegação

WebView dá suporte à navegação programática com os métodos GoBack e GoForward. Esses métodos habilitam a navegação por meio da pilha de páginas WebView e só devem ser chamados depois de inspecionar os valores das propriedades CanGoBack e CanGoForward:

WebView webView = new WebView();
...

// Go backwards, if allowed.
if (webView.CanGoBack)
{
    webView.GoBack();
}

// Go forwards, if allowed.
if (webView.CanGoForward)
{
    webView.GoForward();
}

Quando a navegação de página ocorre em um WebView, iniciado programaticamente ou pelo usuário, ocorrem os seguintes eventos:

  • Navigating, que é gerado quando a navegação da página é iniciada. O objeto WebNavigatingEventArgs que acompanha o evento Navigating define uma propriedade Cancel do tipo bool que pode ser usada para cancelar a navegação.
  • Navigated, que é gerado quando a navegação de página é concluída. O objeto WebNavigatedEventArgs que acompanha o evento Navigated define uma propriedade Result do tipo WebNavigationResult que indica o resultado da navegação.

Manipular permissões no Android

Ao navegar até uma página que solicita acesso ao hardware de gravação do dispositivo, como a câmera ou o microfone, a permissão precisa ser concedida pelo controle WebView. O controle WebView usa o tipo Android.Webkit.WebChromeClient no Android para reagir às solicitações de permissão. No entanto, a implementação WebChromeClient fornecida pelo .NET MAUI ignora solicitações de permissão. Você precisa criar um tipo que herde de MauiWebChromeClient e aprove as solicitações de permissão.

Importante

Personalizar o WebView para aprovar solicitações de permissão, usando essa abordagem, requer a API 26 ou posterior do Android.

As solicitações de permissão de uma página da Web para o controle WebView são diferentes das solicitações de permissão do aplicativo .NET MAUI para o usuário. As permissões de aplicativo do .NET MAUI são solicitadas e aprovadas pelo usuário para todo o aplicativo. O controle WebView depende da capacidade dos aplicativos de acessar o hardware. Para ilustrar esse conceito, considere uma página da Web que solicita acesso à câmera do dispositivo. Mesmo que essa solicitação seja aprovada pelo controle WebView, ainda que o aplicativo do .NET MAUI não tenha aprovação do usuário para acessar a câmera, a página da Web não seria capaz de acessar a câmera.

As etapas a seguir demonstram como interceptar solicitações de permissão do controle WebView para usar a câmera. Se você estiver tentando usar o microfone, as etapas serão semelhantes, exceto que você usaria permissões relacionadas ao microfone em vez de permissões relacionadas à câmera.

  1. Primeiro, adicione as permissões de aplicativo necessárias ao manifesto do Android. Abra o arquivo Platforms/Android/AndroidManifest.xml e adicione o seguinte no nó manifest:

    <uses-permission android:name="android.permission.CAMERA" />
    
  2. Em algum ponto do aplicativo, como quando a página que contém um controle WebView é carregada, solicite permissão do usuário para permitir que o aplicativo acesse a câmera.

    private async Task RequestCameraPermission()
    {
        PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.Camera>();
    
        if (status != PermissionStatus.Granted)
            await Permissions.RequestAsync<Permissions.Camera>();
    }
    
  3. Adicione a seguinte classe à pasta Platforms/Android, alterando o namespace raiz para corresponder ao namespace do projeto:

    using Android.Webkit;
    using Microsoft.Maui.Handlers;
    using Microsoft.Maui.Platform;
    
    namespace MauiAppWebViewHandlers.Platforms.Android;
    
    internal class MyWebChromeClient: MauiWebChromeClient
    {
        public MyWebChromeClient(IWebViewHandler handler) : base(handler)
        {
    
        }
    
        public override void OnPermissionRequest(PermissionRequest request)
        {
            // Process each request
            foreach (var resource in request.GetResources())
            {
                // Check if the web page is requesting permission to the camera
                if (resource.Equals(PermissionRequest.ResourceVideoCapture, StringComparison.OrdinalIgnoreCase))
                {
                    // Get the status of the .NET MAUI app's access to the camera
                    PermissionStatus status = Permissions.CheckStatusAsync<Permissions.Camera>().Result;
    
                    // Deny the web page's request if the app's access to the camera is not "Granted"
                    if (status != PermissionStatus.Granted)
                        request.Deny();
                    else
                        request.Grant(request.GetResources());
    
                    return;
                }
            }
    
            base.OnPermissionRequest(request);
        }
    }
    

    No snippet anterior, a classe MyWebChromeClient herda de MauiWebChromeClient e substitui o método OnPermissionRequest para interceptar solicitações de permissão de página da Web. Cada item de permissão é verificado para ver se ele corresponde à constante de cadeia de caracteres PermissionRequest.ResourceVideoCapture, que representa a câmera. Se uma permissão de câmera for correspondida, o código verificará se o aplicativo tem permissão para usar a câmera. Se ele tiver permissão, a solicitação da página da Web será concedida.

  4. Use o método SetWebChromeClient no controle WebView do Android para definir o cliente chrome como MyWebChromeClient. Os dois seguintes itens demonstram como você pode definir o cliente chrome:

    • Considerando um controle WebView do .NET MAUI chamado theWebViewControl, você pode definir o cliente chrome diretamente na exibição da plataforma, que é o controle Android:

      ((IWebViewHandler)theWebViewControl.Handler).PlatformView.SetWebChromeClient(new MyWebChromeClient((IWebViewHandler)theWebViewControl.Handler));
      
    • Você também pode usar o mapeamento de propriedades do manipulador para forçar todos os controles WebView a usar o cliente chrome. Para obter mais informações, confira Manipuladores.

      O método CustomizeWebViewHandler do snippet a seguir deve ser chamado quando o aplicativo é iniciado, como no método MauiProgram.CreateMauiApp.

      private static void CustomizeWebViewHandler()
      {
      #if ANDROID26_0_OR_GREATER
          Microsoft.Maui.Handlers.WebViewHandler.Mapper.ModifyMapping(
              nameof(Android.Webkit.WebView.WebChromeClient),
              (handler, view, args) => handler.PlatformView.SetWebChromeClient(new MyWebChromeClient(handler)));
      #endif
      }
      

Definir cookies

Os cookies podem ser definidos em um WebView de modo que sejam enviados com a solicitação da Web para a URL especificada. Defina os cookies adicionando objetos Cookie a um CookieContainer e defina o contêiner como o valor da propriedade associável WebView.Cookies. O código a seguir mostra um exemplo:

using System.Net;

CookieContainer cookieContainer = new CookieContainer();
Uri uri = new Uri("https://video2.skills-academy.com/dotnet/maui", UriKind.RelativeOrAbsolute);

Cookie cookie = new Cookie
{
    Name = "DotNetMAUICookie",
    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() };

Neste exemplo, um Cookie é adicionado ao objeto CookieContainer, que é definido como o valor da propriedade WebView.Cookies. Quando o WebView envia uma solicitação da Web para a URL especificada, o cookie é enviado com a solicitação.

Invocar JavaScript

WebView inclui a capacidade de invocar uma função JavaScript do C# e retornar qualquer resultado para o código C# de chamada. Essa interoperabilidade é realizada com o método EvaluateJavaScriptAsync, que é mostrado no seguinte exemplo:

Entry numberEntry = new Entry { Text = "5" };
Label resultLabel = new Label();
WebView webView = new WebView();
...

int number = int.Parse(numberEntry.Text);
string result = await webView.EvaluateJavaScriptAsync($"factorial({number})");
resultLabel.Text = $"Factorial of {number} is {result}.";

O método WebView.EvaluateJavaScriptAsync avalia o JavaScript especificado como o argumento e retorna qualquer resultado como um string. Neste exemplo, a função JavaScript factorial é invocada, que retorna o fatorial de number como resultado. Essa função JavaScript é definida no arquivo HTML local que o WebView carrega e é mostrada no seguinte exemplo:

<html>
<body>
<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>

Configurar o WebView nativo no iOS e no Mac Catalyst

O controle nativo WebView é um MauiWKWebView no iOS e no Mac Catalyst, que deriva de WKWebView. Uma das sobrecargas do construtor MauiWKWebView permite que um objeto WKWebViewConfiguration seja especificado, o que fornece informações sobre como configurar o objeto WKWebView. As configurações típicas incluem a configuração do agente do usuário, a especificação de cookies a serem disponibilizados para o conteúdo da Web e a injeção de scripts personalizados no conteúdo da Web.

Você pode criar um objeto WKWebViewConfiguration em seu aplicativo e, em seguida, configurar as propriedades dele conforme necessário. Como alternativa, você pode chamar o método estático MauiWKWebView.CreateConfiguration para recuperar o objeto WKWebViewConfiguration do .NET MAUI e modificá-lo. O objeto WKWebViewConfiguration pode ser então especificado como um argumento para a sobrecarga do construtor MauiWKWebView.

Como a configuração do WebView nativo não pode ser alterada no iOS e no Mac Catalyst depois que a exibição da plataforma do manipulador é criada, você deve criar um delegado de alocador de manipulador personalizado para modificá-lo:

#if IOS || MACCATALYST
using WebKit;
using CoreGraphics;
using Microsoft.Maui.Platform;
using Microsoft.Maui.Handlers;
#endif
...

#if IOS || MACCATALYST
    Microsoft.Maui.Handlers.WebViewHandler.PlatformViewFactory = (handler) =>
    {
        WKWebViewConfiguration config = MauiWKWebView.CreateConfiguration();
        config.ApplicationNameForUserAgent = "MyProduct/1.0.0";
        return new MauiWKWebView(CGRect.Empty, (WebViewHandler)handler, config);
    };
#endif

Observação

Você deve configurar MauiWKWebView com um WKWebViewConfiguration objeto antes que um WebView seja exibido em seu aplicativo. Locais adequados para fazer isso estão no caminho de inicialização do aplicativo, como em MauiProgram.cs ou App.xaml.cs.

Definir preferências de reprodução de mídia no iOS e no Mac Catalyst

A reprodução de mídia embutida do vídeo HTML5, incluindo reprodução automática e picture in picture, é habilitada por padrão para o WebView no iOS e no Mac Catalyst. Para alterar esse padrão ou definir outras preferências de reprodução de mídia, você deve criar um delegado de alocador de manipulador personalizado, pois as preferências de reprodução de mídia não podem ser alteradas depois que a exibição da plataforma do manipulador é criada. O seguinte código mostra um exemplo de como fazer isso:

#if IOS || MACCATALYST
using WebKit;
using CoreGraphics;
using Microsoft.Maui.Platform;
using Microsoft.Maui.Handlers;
#endif
...

#if IOS || MACCATALYST
    Microsoft.Maui.Handlers.WebViewHandler.PlatformViewFactory = (handler) =>
    {
        WKWebViewConfiguration config = MauiWKWebView.CreateConfiguration();

        // True to play HTML5 videos inliine, false to use the native full-screen controller.
        config.AllowsInlineMediaPlayback = false;

        // True to play videos over AirPlay, otherwise false.
        config.AllowsAirPlayForMediaPlayback = false;

        // True to let HTML5 videos play Picture in Picture.
        config.AllowsPictureInPictureMediaPlayback = false;

        // Media types that require a user gesture to begin playing.
        config.MediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypes.All;

        return new MauiWKWebView(CGRect.Empty, (WebViewHandler)handler, config);
    };
#endif

Para obter mais informações sobre como configurar um WebView no iOS, confira Configurar o WebView nativo no iOS e no Mac Catalyst.

Inspecionar um WebView no Mac Catalyst

Para usar as ferramentas para desenvolvedores do Safari para inspecionar o conteúdo de um WebView no Mac Catalyst, adicione o seguinte código ao seu aplicativo:

#if MACCATALYST
        Microsoft.Maui.Handlers.WebViewHandler.Mapper.AppendToMapping("Inspect", (handler, view) =>
        {
            if (OperatingSystem.IsMacCatalystVersionAtLeast(16, 6))
                handler.PlatformView.Inspectable = true;
        });
#endif

Esse código personaliza o mapeador de propriedades para o WebViewHandler no Mac Catalyst, para tornar o conteúdo de WebView inspecionável pelas ferramentas para desenvolvedores do Safari. Para obter mais informações sobre manipuladores, confira Manipuladores.

Para usar ferramentas para desenvolvedores do Safari com um aplicativo Mac Catalyst:

  1. Abra o Safari em seu Mac.
  2. No Safari, marque a caixa de seleção Safari > Configurações > Avançado > Mostrar menu Desenvolver na barra de menus.
  3. Execute o seu aplicativo Mac Catalyst do .NET MAUI.
  4. No Safari, selecione o menu Desenvolver > {Nome do dispositivo}, em que o espaço reservado {Device name} é o nome do seu dispositivo, como Macbook Pro. Em seguida, selecione a entrada no nome do aplicativo, que também realçará seu aplicativo em execução. Isso fará com que a janela do inspetor da Web apareça.

Iniciar o navegador do sistema

É possível abrir um URI no navegador da Web do sistema com a classe Launcher, que é fornecida por Microsoft.Maui.Essentials. Chame o método OpenAsync do inicializador e passe um argumento string ou Uri que represente o URI a ser aberto:

await Launcher.OpenAsync("https://video2.skills-academy.com/dotnet/maui");

Para obter mais informações, confira Inicializador.