WebView
.NET Multi-platform App UI (.NET MAUI) WebView muestra páginas web remotas, archivos HTML locales y cadenas HTML, en una aplicación. El contenido mostrado como WebView incluye compatibilidad con hojas de estilos en cascada (CSS) y JavaScript. De forma predeterminada, los proyectos de .NET MAUI incluyen los permisos de plataforma necesarios para que WebView muestre una página web remota.
WebView define las siguientes propiedades:
- Cookies, de tipo
CookieContainer
, proporciona almacenamiento para una colección de cookies. - CanGoBack, de tipo
bool
, indica si el usuario puede navegar a páginas anteriores. Se trata de una propiedad de solo lectura. - CanGoForward, de tipo
bool
, indica si el usuario puede navegar hacia delante. Se trata de una propiedad de solo lectura. - Source, de tipo
WebViewSource
, representa la ubicación que WebView muestra.
- Cookies, de tipo
CookieContainer
, proporciona almacenamiento para una colección de cookies. - CanGoBack, de tipo
bool
, indica si el usuario puede navegar a páginas anteriores. Se trata de una propiedad de solo lectura. - CanGoForward, de tipo
bool
, indica si el usuario puede navegar hacia delante. Se trata de una propiedad de solo lectura. - Source, de tipo
WebViewSource
, representa la ubicación que WebView muestra. - UserAgent, de tipo
string
, representa el agente de usuario. El valor predeterminado es el agente de usuario del explorador de plataforma subyacente onull
si no se puede determinar.
Estas propiedades están respaldadas por objetos BindableProperty, lo que significa que pueden ser destinos de los enlaces de datos, y con estilo.
La propiedad Source
se puede establecer en un objeto UrlWebViewSource
o en un objeto HtmlWebViewSource
, que ambos derivan de WebViewSource
. UrlWebViewSource
sirve para cargar una página web especificada con una dirección URL, mientras que un objeto HtmlWebViewSource
sirve para cargar un archivo HTML local o HTML local.
WebView define un evento Navigating
que se genera cuando se inicia la navegación de página y un evento Navigated
que se genera cuando se completa la navegación de página. El objeto WebNavigatingEventArgs
que acompaña al evento Navigating
define una propiedad Cancel
de tipo bool
que se puede usar para cancelar la navegación. El objeto WebNavigatedEventArgs
que acompaña al evento Navigated
define una propiedad Result
de tipo WebNavigationResult
que indica el resultado de la navegación.
Importante
WebView debe especificar sus propiedades HeightRequest y WidthRequest cuando están contenidos en HorizontalStackLayoutStackLayout o VerticalStackLayout. Si no puedes especificar estas propiedades, WebView no se representará.
Mostrar una página web
Para mostrar una página web remota, establece la propiedad Source
en una string
que especifique el URI:
<WebView Source="https://learn.microsoft.com/dotnet/maui" />
El código de C# equivalente es el siguiente:
WebView webvView = new WebView
{
Source = "https://learn.microsoft.com/dotnet/maui"
};
Los URI deben tener un formato completo con el protocolo especificado.
Nota:
A pesar de que la propiedad Source
es de tipo WebViewSource
, la propiedad se puede establecer en un URI basado en cadenas. Esto se debe a que .NET MAUI incluye un convertidor de tipos y un operador de conversión implícito, que convierte el URI basado en cadenas en un objeto UrlWebViewSource
.
Configuración de la Seguridad de transporte de aplicación en iOS y Mac Catalyst
Desde la versión 9, iOS solo permitirá que la aplicación se comunique con servidores seguros. Una aplicación tiene que optar por habilitar la comunicación con servidores no seguros.
La siguiente configuración de Info.plist muestra cómo habilitar un dominio específico para omitir los requisitos de Apple Transport Security (ATS):
<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>
Se recomienda habilitar solo dominios específicos para omitir ATS, lo que te permite usar sitios de confianza al tiempo que te beneficias de la seguridad adicional en dominios que no son de confianza.
La siguiente configuración de Info.plist muestra cómo deshabilitar ATS para una aplicación:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Importante
Si la aplicación requiere una conexión a un sitio web no seguro, siempre debes escribir el dominio como una excepción mediante la clave NSExceptionDomains
en lugar de desactivar ATS completamente con la clave NSAllowsArbitraryLoads
.
Mostrar HTML local
Para mostrar HTML insertado, establece la propiedad Source
en un objeto HtmlWebViewSource
:
<WebView>
<WebView.Source>
<HtmlWebViewSource Html="<HTML><BODY><H1>.NET MAUI</H1><P>Welcome to WebView.</P></BODY><HTML>" />
</WebView.Source>
</WebView>
En XAML, las cadenas HTML se pueden volver ilegibles debido a que se usan los símbolos <
y >
como caracteres de escape. Por lo tanto, para mejorar la legibilidad, el código HTML se puede insertar en una sección 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>
El código de C# equivalente es el siguiente:
WebView webView = new WebView
{
Source = new HtmlWebViewSource
{
Html = @"<HTML><BODY><H1>.NET MAUI</H1><P>Welcome to WebView.</P></BODY></HTML>"
}
};
Mostrar un archivo HTML local
Para mostrar un archivo HTML local, agrega el archivo a la carpeta Resources\Raw del proyecto de aplicación y establece su acción de compilación en MauiAsset. A continuación, el archivo se puede cargar desde el HTML insertado que se define en un objeto HtmlWebViewSource
establecido como el valor de la propiedad 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>
El archivo HTML local puede cargar hojas de estilo en cascada (CSS), JavaScript e imágenes, si también se han agregado al proyecto de aplicación con la acción de compilación MauiAsset.
Para obtener más información sobre recursos sin procesar, consulta Recursos sin procesar.
Recargar contenido
WebView tiene un método Reload
al que se puede llamar para recargar su origen:
WebView webView = new WebView();
...
webView.Reload();
Cuando se invoca el método Reload
, se desencadena el evento ReloadRequested
, lo que indica que se ha realizado una solicitud para recargar el contenido actual.
Realización de la navegación
WebView admite la navegación programática con los métodos GoBack
y GoForward
. Estos métodos habilitan la navegación de páginas apiladas WebView y solo deben llamarse después de inspeccionar los valores de las propiedades CanGoBack
y CanGoForward
:
WebView webView = new WebView();
...
// Go backwards, if allowed.
if (webView.CanGoBack)
{
webView.GoBack();
}
// Go forwards, if allowed.
if (webView.CanGoForward)
{
webView.GoForward();
}
Cuando la navegación de páginas se produce en WebView, ya sea iniciada mediante programación o por el usuario, se producen los siguientes eventos:
Navigating
, que se genera cuando se inicia la navegación de páginas. El objetoWebNavigatingEventArgs
que acompaña al eventoNavigating
define una propiedadCancel
de tipobool
que se puede usar para cancelar la navegación.Navigated
, que se genera cuando se completa la navegación de páginas. El objetoWebNavigatedEventArgs
que acompaña al eventoNavigated
define una propiedadResult
de tipoWebNavigationResult
que indica el resultado de la navegación.
Control de permisos en Android
Al navegar a una página que solicita acceso al hardware de grabación del dispositivo, como la cámara o el micrófono, el control WebView debe conceder el permiso. El control WebView
usa el tipo Android.Webkit.WebChromeClient en Android para reaccionar a las solicitudes de permisos. Sin embargo, la implementación de WebChromeClient
proporcionada por .NET MAUI omite las solicitudes de permisos. Debes crear un nuevo tipo que herede de MauiWebChromeClient
y apruebe las solicitudes de permisos.
Importante
La personalización de WebView
para aprobar solicitudes de permisos, con este enfoque, requiere la API de Android 26 o posterior.
Las solicitudes de permisos de una página web al control WebView
son diferentes de las solicitudes de permisos de la aplicación .NET MAUI al usuario. El usuario solicita y aprueba los permisos de la aplicación .NET MAUI para toda la aplicación. El control WebView
depende de la capacidad de las aplicaciones para acceder al hardware. Para ilustrar este concepto, piensa en una página web que solicita acceso a la cámara del dispositivo. Incluso si el control WebView
aprueba esa solicitud, si la aplicación .NET MAUI no tuviera la aprobación del usuario para acceder a la cámara, la página web no podría acceder a la cámara.
En los pasos siguientes se muestra cómo interceptar las solicitudes de permiso del control WebView
para usar la cámara. Si intentas usar el micrófono, los pasos serían similares, excepto que usarías permisos relacionados con el micrófono en lugar de permisos relacionados con la cámara.
En primer lugar, agrega los permisos de aplicación necesarios al manifiesto de Android. Abre el archivo Platforms/Android/AndroidManifest.xml y agrega lo siguiente en el nodo
manifest
:<uses-permission android:name="android.permission.CAMERA" />
En algún punto de la aplicación, como cuando se carga la página que contiene un control
WebView
, solicita permiso al usuario para permitir que la aplicación acceda a la cámara.private async Task RequestCameraPermission() { PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.Camera>(); if (status != PermissionStatus.Granted) await Permissions.RequestAsync<Permissions.Camera>(); }
Agrega la siguiente clase a la carpeta Platforms/Android y cambia el espacio de nombres raíz para que coincida con el espacio de nombres del proyecto:
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); } }
En el fragmento de código anterior, la clase
MyWebChromeClient
hereda deMauiWebChromeClient
e invalida el métodoOnPermissionRequest
para interceptar las solicitudes de permisos de páginas web. Se comprueba cada elemento de permiso para ver si coincide con la constante de cadenaPermissionRequest.ResourceVideoCapture
, que representa la cámara. Si coincide con un permiso de cámara, el código comprueba si la aplicación tiene permiso para usar la cámara. Si tiene permiso, se concede la solicitud de la página web.Usa el método SetWebChromeClient en el control de
WebView
Android para establecer el cliente chrome enMyWebChromeClient
. Los dos elementos siguientes muestran cómo puedes establecer el cliente chrome:Dado un control
WebView
de .NET MAUI denominadotheWebViewControl
, puedes establecer el cliente chrome directamente en la vista de plataforma, que es el control Android:((IWebViewHandler)theWebViewControl.Handler).PlatformView.SetWebChromeClient(new MyWebChromeClient((IWebViewHandler)theWebViewControl.Handler));
También puedes usar la asignación de propiedades del controlador para forzar que todos los controles
WebView
usen el cliente chrome. Para obtener más información, consulta Controladores.Se debe llamar al método
CustomizeWebViewHandler
del fragmento de código siguiente cuando se inicia la aplicación, como en el métodoMauiProgram.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 }
Establecimiento de cookies
Las cookies se pueden establecer en WebView para que se envíen con la solicitud web a la dirección URL especificada. Para establecer las cookies, agrega objetos Cookie
a CookieContainer
y luego establece el contenedor como el valor de la propiedad enlazable WebView.Cookies
. El código siguiente muestra un ejemplo:
using System.Net;
CookieContainer cookieContainer = new CookieContainer();
Uri uri = new Uri("https://learn.microsoft.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() };
En este ejemplo, se agrega un único Cookie
al objeto CookieContainer
, que luego se establece como el valor de la propiedad WebView.Cookies
. Cuando WebView envía una solicitud web a la dirección URL especificada, la cookie se envía con la solicitud.
Invocación de JavaScript
WebView incluye la capacidad de invocar una función de JavaScript desde C# y devolver cualquier resultado al código C# que realiza la llamada. Esta interoperabilidad se realiza con el método EvaluateJavaScriptAsync
, que se muestra en el siguiente ejemplo:
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}.";
El método WebView.EvaluateJavaScriptAsync
evalúa el JavaScript especificado como argumento y devuelve cualquier resultado como string
. En este ejemplo, se invoca la función factorial
de JavaScript, que devuelve el factorial de number
como resultado. Esta función de JavaScript se define en el archivo HTML local que carga WebView y se muestra en el ejemplo siguiente:
<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>
Configuración de WebView nativo en iOS y Mac Catalyst
El control nativo WebView es MauiWKWebView
en iOS y Mac Catalyst, que deriva de WKWebView
. Una de las sobrecargas del constructor MauiWKWebView
permite especificar un objeto WKWebViewConfiguration
, que proporciona información sobre cómo configurar el objeto WKWebView
. Las configuraciones típicas incluyen establecer el agente de usuario, especificar cookies para que estén disponibles para el contenido web e insertar scripts personalizados en el contenido web.
Puedes crear un objeto WKWebViewConfiguration
en la aplicación y después configurar sus propiedades según sea necesario. De manera alternativa, se puede llamar al método estático MauiWKWebView.CreateConfiguration
para recuperar el objeto WKWebViewConfiguration
de .NET MAUI y después modificarlo. A continuación, el objeto WKWebViewConfiguration
se puede especificar como argumento para la sobrecarga del constructor MauiWKWebView
.
Dado que la configuración del WebView nativo no se puede cambiar en iOS y Mac Catalyst una vez creada la vista de plataforma del controlador, se debe crear un delegado de fábrica de controlador personalizado para modificarlo:
#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
Nota:
Se debe configurar MauiWKWebView
con un objeto WKWebViewConfiguration
antes de que se muestre WebView en la aplicación. Las ubicaciones adecuadas para hacerlo se encuentran en la ruta de inicio de la aplicación, como en MauiProgram.cs o App.xaml.cs.
Establecer preferencias de reproducción multimedia en iOS y Mac Catalyst
La reproducción multimedia insertada de vídeo HTML5, incluida la reproducción automática y la imagen dentro de imagen, está habilitada de forma predeterminada para WebView en iOS y Mac Catalyst. Para cambiar este valor predeterminado o establecer otras preferencias de reproducción multimedia, debes crear un delegado de fábrica de controlador personalizado, ya que las preferencias de reproducción multimedia no se pueden cambiar una vez creada la vista de plataforma del controlador. El código siguiente muestra un ejemplo de esto:
#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 obtener más información sobre cómo configurar WebView en iOS, consulta Configuración de WebView nativo en iOS y Mac Catalyst.
Inspección de un WebView en Mac Catalyst
Para usar las herramientas de desarrollo de Safari para inspeccionar el contenido de WebView en Mac Catalyst, agrega el código siguiente a la aplicación:
#if MACCATALYST
Microsoft.Maui.Handlers.WebViewHandler.Mapper.AppendToMapping("Inspect", (handler, view) =>
{
if (OperatingSystem.IsMacCatalystVersionAtLeast(16, 6))
handler.PlatformView.Inspectable = true;
});
#endif
Este código personaliza el asignador de propiedades para WebViewHandler
en Mac Catalyst para hacer que el contenido WebView sea inspeccionable por las herramientas de desarrollo de Safari. Para más información sobre los controladores, consulta Controladores.
Para usar las herramientas de desarrollo de Safari con una aplicación Mac Catalyst:
- Abre Safari en el equipo Mac.
- En Safari, selecciona la casilla Safari > Settings >Advanced > Show Develop menu in menu bar.
- Ejecuta la aplicación .NET MAUI Mac Catalyst.
- En Safari, selecciona el menú Develop > {Nombre del dispositivo}, donde el marcador de posición
{Device name}
es el nombre del dispositivo, comoMacbook Pro
. A continuación, selecciona la entrada en el nombre de la aplicación, que también resaltará la aplicación en ejecución. Esto hará que aparezca la ventana Inspector web.
Utiliza el explorador del sistema
Es posible abrir un URI en el explorador web del sistema con la clase Launcher
, que Microsoft.Maui.Essentials
proporciona. Llama al método OpenAsync
del iniciador y pasa un argumento string
o Uri
que representa el URI que se va a abrir:
await Launcher.OpenAsync("https://learn.microsoft.com/dotnet/maui");
Para más información, consulta Launcher.
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de