Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Además de cargar contenido remoto, el contenido también se puede cargar localmente en WebView2. Se pueden usar varias soluciones para cargar contenido local en un control WebView2, entre las que se incluyen:
- Navegar a una dirección URL de archivo.
- Navegar a una cadena HTML.
- Asignación de nombre de host virtual.
- Controlar el
WebResourceRequestedevento.
Contenido detallado:
- Seleccionar un enfoque
- Cargar contenido local navegando a una dirección URL de archivo
- Cargar contenido local navegando a una cadena HTML
- Cargar contenido local mediante la asignación de nombres de host virtual
- Cargar contenido local mediante el control del evento WebResourceRequested
- Ver también
Seleccionar un enfoque
Las distintas maneras de cargar contenido local en un control WebView2 admiten los escenarios siguientes:
| Escenario | Navegando a una dirección URL de archivo | Navegando a una cadena HTML | Mediante la asignación de nombres de host virtual | Mediante el uso de WebResourceRequested |
|---|---|---|---|---|
| API de DOM basadas en origen | ✔️ Sí | No❌ | ✔️ Sí | ✔️ Sí |
| API de DOM que requieren contexto seguro | No❌ | No❌ | ✔️ Sí | ✔️ Sí |
| Contenido dinámico | No❌ | ✔️ Sí | No❌ | ✔️ Sí |
| Recursos web adicionales | ✔️ Sí | No❌ | ✔️ Sí | ✔️ Sí |
| Recursos web adicionales resueltos en el proceso de WebView2 | ✔️ Sí | No❌ | ✔️ Sí | No❌ |
Estos escenarios se describen a continuación.
Cargar contenido local navegando a una dirección URL de archivo
WebView2 permite navegaciones a URL de archivos, para cargar HTML básico o un PDF. Este es el enfoque más sencillo y eficiente para cargar contenido local. Sin embargo, es menos flexible que los otros enfoques. Al igual que en un explorador web, las direcciones URL de archivo están limitadas en algunas funcionalidades:
El documento tiene un origen que es único para su ruta de acceso de archivo. Esto significa que las API web que requieren un origen como
localStorageorindexedDBfuncionarán, pero los datos almacenados no estarán disponibles para otros documentos locales cargados desde otras rutas de archivo.Algunas API web se limitan solo a direcciones URL HTTPS seguras y no están disponibles para los documentos cargados por direcciones URL de archivo. Esto incluye API, por ejemplo
navigator.mediaDevices.getUserMedia(), adquirir vídeo o sonido,navigator.geolocation.getCurrentPosition()acceder a la ubicación del dispositivo oNotification.requestPermission()solicitar el permiso del usuario para mostrar notificaciones.Para cada recurso, se debe especificar la ruta completa.
Para permitir referencias a otros archivos locales desde URI de archivo, o para mostrar archivos XML con transformaciones XSL aplicadas, puede establecer el argumento del
--allow-file-access-from-filesexplorador. Consulte la propiedad CoreWebView2EnvironmentOptions.AdditionalBrowserArguments .
Consideraciones para cargar contenido local navegando a una dirección URL de archivo
Las direcciones URL de archivo se comportan como lo hacen en el explorador. Por ejemplo, no puede crear un XMLHttpRequest (XHR) en una dirección URL de archivo, porque no está trabajando en el contexto de una página web.
Debe especificar la ruta de acceso completa del archivo, para cada recurso. Por ejemplo:
file:///C:/Users/username/Documents/GitHub/Demos/demo-to-do/index.html
Recursos entre orígenes
Al especificar una dirección URL de archivo, la aplicación navega a un archivo en el disco, no a un dominio en la red. Como resultado, no es posible usar recursos entre orígenes en el documento resultante.
API de DOM basadas en origen
Un documento cargado a través de una URL de archivo tiene un origen que es único para su ruta de acceso al archivo, al igual que en el navegador. API web que requieren un origen como localStorage o indexedDB funcionarán. Sin embargo, no se considera que diferentes documentos cargados desde diferentes direcciones URL de archivo provienen del mismo origen y no tendrán acceso a los mismos datos almacenados.
API de DOM que requieren contexto seguro
Algunas API web se limitan solo a direcciones URL HTTPS seguras y no están disponibles para los documentos cargados por direcciones URL de archivo. Esto incluye API, por ejemplo navigator.mediaDevices.getUserMedia() , adquirir vídeo o sonido, navigator.geolocation.getCurrentPosition() acceder a la ubicación del dispositivo o Notification.requestPermission() solicitar el permiso del usuario para mostrar notificaciones. Consulta Contextos seguros en MDN para más información.
Contenido dinámico
Al cargar un documento a través de una dirección URL de archivo, el contenido del documento procede de archivos estáticos en el disco. Esto significa que no es posible modificar dinámicamente este contenido local. Esto es diferente de cargar documentos desde un servidor web, donde cada respuesta se puede generar dinámicamente.
Recursos web adicionales
La resolución de URL relativa también funciona para los documentos cargados a través de una URL de archivo. Esto significa que el documento cargado puede tener referencias a recursos web adicionales, como archivos CSS, de script o de imagen, que también se sirven a través de direcciones URL de archivo.
Recursos web adicionales resueltos en el proceso de WebView2
Las direcciones URL de archivo se resuelven en procesos WebView2. Esta es una opción más rápida que WebResourceRequested, que se resuelve en el subproceso de interfaz de usuario del proceso de la aplicación host.
API para cargar contenido local navegando a una dirección URL de archivo
Ejemplo de una dirección URL de archivo
En esta sección se muestra el aspecto de una dirección URL de archivo para una ruta de acceso de archivo de contenido local de una manera independiente de la plataforma.
Una aplicación WebView2 necesita codificar direcciones URL de archivos locales con un prefijo y barras file:/// diagonales. Por ejemplo, para el ejemplo de Demo To Do, la ruta sería:
file:///C:/Users/username/Documents/GitHub/Demos/demo-to-do/index.html
Para copiar la ruta de acceso completa con el prefijo "file" para un archivo local:
Opcionalmente, clona el repositorio de demostraciones para que tengas una copia local. Consulte el Paso 5: Clonar el repositorio de demostraciones en Instalación de la extensión DevTools para Visual Studio Code.
En Microsoft Edge, presione Ctrl+O para abrir un archivo. Abra un archivo local
.html, como el archivoDemos/demo-to-do/index.htmlclonado localmente:C:\Users\username\Documents\GitHub\Demos\demo-to-do\index.htmlLa barra de direcciones no muestra inicialmente el
file:///prefijo, pero comienza con la letra de la unidad:C:/Users/username/Documents/GitHub/Demos/demo-to-do/index.html
Haga clic en la barra de direcciones y después presione la tecla Inicio o presione Ctrl+A para seleccionar toda la ruta de acceso.
Toda la ruta de acceso del archivo, incluida
file:///, se copia en el búfer del Portapapeles, por lo que puede pegar la ruta completa, incluido elfile:///prefijo:file:///C:/Users/username/Documents/GitHub/Demos/demo-to-do/index.html
Vea también:
- Demo To Do: página representada
- Demo To Do: código fuente
- Paso 5: Clone the Demos repo in Installing the DevTools extension for Visual Studio Code.
Ejemplo de navegación a la dirección URL de un archivo
webView.CoreWebView2.Navigate(
"file:///C:/Users/username/Documents/GitHub/Demos/demo-to-do/index.html");
Cargar contenido local navegando a una cadena HTML
Otro método para cargar contenido local es el NavigateToString método. Este enfoque carga el contenido en WebView2 directamente desde una cadena. Esto puede ser útil si vas a empaquetar el contenido a través del código de la aplicación o si quieres crear el contenido dinámicamente.
Otro escenario en el que navegar a una cadena puede ser útil es si desea cargar contenido al que no se puede acceder a través de una dirección URL. Por ejemplo, si tiene una representación en memoria de un documento HTML, podría usar el NavigateToString método para cargar ese contenido en el control WebView2. Esto puede ser útil si desea evitar la necesidad de escribir el contenido en un archivo o servidor antes de cargarlo en el control.
Consideraciones para cargar contenido local navegando a una cadena HTML
La cadena de contenido HTML que se pasa al NavigateToString método tiene un límite de tamaño de 2 MB. Este límite de tamaño puede ser fácil de superar cuando la cadena incluye recursos adicionales insertados. Si se excede este límite de tamaño, se devuelve un error: "El valor no se encuentra dentro del rango esperado".
API de DOM basadas en origen
Un documento cargado mediante el NavigateToString método tiene su ubicación establecida y about:blank su origen establecido en null. Esto significa que no se pueden usar las API web que dependen de un origen definido, como localStorage o indexedDB.
API de DOM que requieren contexto seguro
Algunas API web se limitan solo a direcciones URL HTTPS seguras y no están disponibles para los documentos cargados a través del NavigateToString método porque su ubicación está establecida en about:blank. Esto incluye API, por ejemplo navigator.mediaDevices.getUserMedia() , adquirir vídeo o sonido, navigator.geolocation.getCurrentPosition() acceder a la ubicación del dispositivo o Notification.requestPermission() solicitar el permiso del usuario para mostrar notificaciones. Consulta Contextos seguros en MDN para más información.
Contenido dinámico
Al cargar contenido local a través del NavigateToString método, está proporcionando directamente el contenido como parámetro para el método. Esto significa que tiene el control del contenido en tiempo de ejecución y puede generarlo dinámicamente si es necesario.
Recursos web adicionales
La carga de contenido local mediante el NavigateToString método no permite que el documento resultante haga referencia a recursos web adicionales, como archivos CSS, de imagen o de script. El método solo le permite especificar el contenido de cadena del documento HTML. Para hacer referencia a recursos web adicionales desde el documento HTML, use uno de los otros métodos descritos en este artículo o represente esos recursos web adicionales en línea en el documento HTML.
Recursos web adicionales resueltos en el proceso de WebView2
NavigateToString no admite recursos web adicionales, como se mencionó anteriormente.
API para cargar contenido local navegando a una cadena HTML
Ejemplo de representación de cadena de una página web
La siguiente es la representación de cadena de la página web de Demo To Do . La lista a continuación ha agregado ajuste de línea para facilitar la lectura. En la práctica, estas líneas se concatenan en una sola línea larga:
`<html lang="en"><head>\n
<meta charset="UTF-8">\n
<meta name="viewport" content="width=device-width, initial-scale=1.0">\n
<title>TODO app</title>\n
<link rel="stylesheet" href="styles/light-theme.css" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)">\n
<link rel="stylesheet" href="styles/dark-theme.css" media="(prefers-color-scheme: dark)">\n
<link rel="stylesheet" href="styles/base.css">\n
<link rel="stylesheet" href="styles/to-do-styles.css">\n
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>📋
</text></svg>">\n
</head>\n\n
<body>\n
<h1>📋 My tasks</h1>\n
<form>\n
<div class="new-task-form" tabindex="0">\n
<label for="new-task">➕ Add a task</label>\n
<input id="new-task" autocomplete="off" type="text" placeholder="Try typing 'Buy milk'" title="Click to start adding a task">\n
<input type="submit" value="➡️">\n
</div>\n
<ul id="tasks"><li class="divider">No tasks defined</li></ul>\n
</form>\n\n \x3Cscript src="to-do.js">\x3C/script>\n \n\n
</body>
</html>`
Para obtener la cadena anterior:
Ve a Demo To Do.
Haga clic con el botón derecho en la página web y, a continuación, seleccione Inspeccionar para abrir DevTools.
En la consola de DevTools, escriba:
document.body.parentElement.outerHTML. La Consola genera una representación de cadena de la página web:
Ejemplo de navegación a una cadena HTML
// Define htmlString with the string representation of HTML as above.
webView.CoreWebView2.NavigateToString(htmlString);
Cargar contenido local mediante la asignación de nombres de host virtual
Otra manera de cargar contenido local en un control WebView2 es usar la asignación de nombre de host virtual. Esto implica asignar un nombre de dominio local a una carpeta local, de modo que cuando el control WebView2 intente cargar un recurso para ese dominio, cargue el contenido desde la ubicación de la carpeta local especificada en su lugar. El origen del documento también será el nombre del host virtual.
Este enfoque le permite especificar el acceso entre orígenes mediante la CoreWebView2HostResourceAccessKind enumeración.
Debido a una limitación actual, los archivos multimedia a los que se accede mediante un nombre de host virtual pueden tardar en cargarse.
Consideraciones para cargar contenido local mediante la asignación de nombres de host virtual
API de DOM basadas en origen
El contenido local cargado a través de la asignación de nombres de host virtual da como resultado un documento que tiene una dirección URL HTTP o HTTPS y un origen correspondiente. Esto significa que las API web que requieren un origen como localStorage or indexedDB funcionarán y otros documentos que pertenezcan al mismo origen podrán usar los datos almacenados. Para más información, consulte Política de mismo origen en MDN.
API de DOM que requieren contexto seguro
Algunas API web solo se limitan a direcciones URL HTTPS seguras. El uso de la asignación de nombres de host virtual proporciona una dirección URL HTTPS para el contenido local. Esto significa que están disponibles las API para navigator.mediaDevices.getUserMedia() adquirir vídeo o sonido, navigator.geolocation.getCurrentPosition() acceder a la ubicación del dispositivo o Notification.requestPermission() solicitar el permiso del usuario para mostrar notificaciones. Consulta Contextos seguros en MDN para más información.
Contenido dinámico
Al cargar contenido local a través de una asignación de nombre de host virtual, está asignando un nombre de host virtual a una carpeta local que contiene archivos estáticos en el disco. Esto significa que no es posible modificar dinámicamente este contenido local. Esto es diferente de cargar documentos desde un servidor web, donde cada respuesta se puede generar dinámicamente.
Recursos web adicionales
El contenido local que se carga a través de la asignación de nombres de host virtual tiene una dirección URL HTTP o HTTPS que admite la resolución relativa de direcciones URL. Esto significa que el documento cargado puede tener referencias a recursos web adicionales, como CSS, script o archivos de imagen que también se sirven a través de la asignación de nombres de host virtuales, excepto los mapas de origen; consulte Mapas de origen con asignación de nombres de host virtual a continuación.
Recursos web adicionales resueltos en el proceso de WebView2
Las direcciones URL de nombre de host virtual se resuelven en procesos WebView2. Esta es una opción más rápida que WebResourceRequested, que se resuelve en el subproceso de interfaz de usuario del proceso de la aplicación host.
Mapas de origen con asignación de nombres de host virtual
Los mapas de origen son necesarios para depurar el código fuente del contenido compilado, incluidos:
- JavaScript transpilado, como TypeScript o JavaScript minimizado.
- CSS compilado, como SASS o SCSS.
WebView2 no carga mapas de origen a los que hace referencia el contenido que se cargó mediante la asignación de nombre de host virtual.
Por ejemplo, suponga que WebView2 se carga main.js a través de la asignación de nombre de host virtual. Si main.js hace referencia main.js.map como su mapa de origen, main.js.map no se cargará automáticamente.
Para usar mapas de origen junto con la asignación de nombre de host virtual, genere mapas de origen en línea durante la compilación del contenido. Los mapas de origen en línea se incrustan dentro del archivo compilado correspondiente.
API para cargar contenido local mediante la asignación de nombres de host virtual
Ejemplo de asignación de nombres de host virtual
webView.CoreWebView2.SetVirtualHostNameToFolderMapping("demo",
"C:\Github\Demos\demo-to-do", CoreWebView2HostResourceAccessKind.DenyCors);
webView.CoreWebView2.Navigate("https://demo/index.html");
Cargar el contenido local mediante el control del WebResourceRequested evento
Otra manera de hospedar contenido local en un control WebView2 consiste en confiar en el WebResourceRequested evento. Este evento se desencadena cuando el control intenta cargar un recurso. Puede usar este evento para interceptar la solicitud y proporcionar el contenido local, como se describe en Administración personalizada de solicitudes de red.
WebResourceRequested le permite personalizar el comportamiento del contenido local por solicitud. Esto significa que puede decidir qué solicitudes interceptar y para las que proporcionar su propio contenido, y qué solicitudes debe permitir que el control WebView2 controle normalmente. Sin embargo, la personalización del comportamiento requiere más código, como la asignación de host virtual, y requiere conocimientos de HTTP para poder construir una respuesta adecuada.
Desde la perspectiva de WebView2, el recurso habrá llegado a través de la red y WebView2 se adherirá a los encabezados establecidos por la aplicación como parte de la respuesta. El uso del WebResourceRequested evento también es más lento que otros enfoques, debido a la comunicación entre procesos y al procesamiento necesarios para cada solicitud.
Registro de esquemas personalizados
Si desea utilizar un esquema personalizado para realizar la solicitud de recurso web que genera el WebResourceRequested evento, consulte Registro de esquema personalizado en Información general de API de WebView2.
Consideraciones para cargar contenido local mediante el control del WebResourceRequested evento
API de DOM basadas en origen
El contenido local cargado da como WebResourceRequested resultado un documento que tiene una dirección URL HTTP o HTTPS y un origen correspondiente. Esto significa que las API web que requieren un origen como localStorage or indexedDB funcionarán y otros documentos que pertenezcan al mismo origen podrán usar los datos almacenados. Para más información, consulte Política de mismo origen en MDN.
API de DOM que requieren contexto seguro
Algunas API web solo se limitan a direcciones URL HTTPS seguras. El uso WebResourceRequested le permite reemplazar las solicitudes de recursos web de dirección URL HTTPS por su propio contenido local. Esto significa que están disponibles las API para navigator.mediaDevices.getUserMedia() adquirir vídeo o sonido, navigator.geolocation.getCurrentPosition() acceder a la ubicación del dispositivo o Notification.requestPermission() solicitar el permiso del usuario para mostrar notificaciones. Consulta Contextos seguros en MDN para más información.
Contenido dinámico
Al cargar contenido local a través de WebResourceRequested, especifique el contenido local que se cargará en el controlador de eventos. Esto significa que tiene el control del contenido en tiempo de ejecución y puede generarlo dinámicamente si es necesario.
Recursos web adicionales
WebResourceRequested modifica el contenido que se carga a través de direcciones URL HTTP o HTTPS, que admiten la resolución relativa de direcciones URL. Esto significa que el documento resultante puede tener referencias a recursos web adicionales, como CSS, script o archivos de imagen que también se sirven a través de WebResourceRequested, excepto los mapas de origen; consulte Mapas de origen con el WebResourceRequested evento, a continuación.
Recursos web adicionales resueltos en el proceso de WebView2
Al cargar contenido a través de una URL de archivo o una asignación de nombre de host virtual, la resolución se produce en los procesos WebView2. Sin embargo, el WebResourceRequested evento se genera en el subproceso de interfaz de usuario de WebView2 del proceso de la aplicación host, lo que puede provocar una carga más lenta del documento resultante.
- WebView2 primero pausa la carga de la página web para esperar a que el evento se envíe al proceso de la aplicación host.
- WebView2 espera a que el subproceso de la interfaz de usuario esté disponible.
- WebView2 espera a que el código de la aplicación controle el evento.
Esto puede tardar algún tiempo. Asegúrese de limitar las llamadas solo a AddWebResourceRequestedFilter los recursos web que deben generar el WebResourceRequested evento.
El origen se mapea con el WebResourceRequested evento
Los mapas de origen son necesarios para depurar el código fuente del contenido compilado, incluidos:
- JavaScript transpilado, como TypeScript o JavaScript minimizado.
- CSS compilado, como SASS o SCSS.
WebView2 no carga mapas de origen a los que hace referencia el contenido que se cargó mediante el WebResourceRequested evento.
Por ejemplo, supongamos que carga main.js el WebResourceRequested controlador de eventos estableciendo la Response propiedad de CoreWebView2WebResourceRequestedEventArgs. Si main.js las referencias main.js.map como su mapa de origen:
-
main.js.mapno se cargará automáticamente. - No
WebResourceRequestedse volverá a llamar al controlador de eventos para cargarmain.js.map.
Para usar mapas de origen junto con WebResourceRequested, use uno de los siguientes enfoques:
Genere mapas de origen en línea durante la compilación del contenido. Los mapas de origen en línea se incrustan dentro del archivo compilado correspondiente.
O bien, el origen independiente en línea se asigna al contenido en tiempo de ejecución en el
WebResourceRequestedcontrolador de eventos. Use este enfoque solo si el sistema de compilación no admite mapas de origen en línea.
API para cargar contenido local mediante el WebResourceRequested control del evento
Ejemplo de control del evento WebResourceRequested
// Reading of response content stream happens asynchronously, and WebView2 does not
// directly dispose the stream once it read. Therefore, use the following stream
// class, which properly disposes when WebView2 has read all data. For details, see
// [CoreWebView2 does not close stream content](https://github.com/MicrosoftEdge/WebView2Feedback/issues/2513).
class ManagedStream : Stream {
public ManagedStream(Stream s)
{
s_ = s;
}
public override bool CanRead => s_.CanRead;
public override bool CanSeek => s_.CanSeek;
public override bool CanWrite => s_.CanWrite;
public override long Length => s_.Length;
public override long Position { get => s_.Position; set => s_.Position = value; }
public override void Flush()
{
throw new NotImplementedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
return s_.Seek(offset, origin);
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
int read = 0;
try
{
read = s_.Read(buffer, offset, count);
if (read == 0)
{
s_.Dispose();
}
}
catch
{
s_.Dispose();
throw;
}
return read;
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
private Stream s_;
}
webView.CoreWebView2.AddWebResourceRequestedFilter("https://demo/*",
CoreWebView2WebResourceContext.All);
webView.CoreWebView2.WebResourceRequested += delegate (object sender,
CoreWebView2WebResourceRequestedEventArgs args)
{
string assetsFilePath = "C:\\Demo\\" +
args.Request.Uri.Substring("https://demo/*".Length - 1);
try
{
FileStream fs = File.OpenRead(assetsFilePath);
ManagedStream ms = new ManagedStream(fs);
string headers = "";
if (assetsFilePath.EndsWith(".html"))
{
headers = "Content-Type: text/html";
}
else if (assetsFilePath.EndsWith(".jpg"))
{
headers = "Content-Type: image/jpeg";
} else if (assetsFilePath.EndsWith(".png"))
{
headers = "Content-Type: image/png";
}
else if (assetsFilePath.EndsWith(".css"))
{
headers = "Content-Type: text/css";
}
else if (assetsFilePath.EndsWith(".js"))
{
headers = "Content-Type: application/javascript";
}
args.Response = webView.CoreWebView2.Environment.CreateWebResourceResponse(
ms, 200, "OK", headers);
}
catch (Exception)
{
args.Response = webView.CoreWebView2.Environment.CreateWebResourceResponse(
null, 404, "Not found", "");
}
};
Vea también
- Administrar el contenido cargado en WebView2 en Información general sobre las API de WebView2
- Página representada de Demo To Do