Hospedaje e implementación de ASP.NET Core Blazor WebAssembly
Nota
Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión de .NET 9 de este artículo.
Advertencia
Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulta la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulta la versión .NET 8 de este artículo.
Importante
Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.
Para la versión actual, consulte la versión de .NET 9 de este artículo.
En este artículo se explica cómo hospedar e implementar Blazor WebAssembly con ASP.NET Core, redes de entrega de contenido (CDN), servidores de archivos y GitHub Pages.
Con el modelo de hospedaje de Blazor WebAssembly:
- La aplicación Blazor, sus dependencias y el entorno de ejecución de .NET se descargan en el explorador en paralelo.
- La aplicación se ejecuta directamente en el subproceso de interfaz de usuario del explorador.
Este artículo pertenece al escenario de implementación donde la aplicación Blazor se coloca en un servidor o servicio web de hospedaje estático; .NET no se usa para suministrar la aplicación Blazor. Esta estrategia se trata en la sección Implementación independiente, que incluye información sobre cómo hospedar una aplicación Blazor WebAssembly como una subaplicación de IIS.
Se admiten las estrategias de implementación siguientes:
- Una aplicación ASP.NET Core suministra la aplicación Blazor. Esta estrategia se trata en la sección Implementación hospedada con ASP.NET Core.
- La aplicación Blazor se coloca en un servicio o servidor web de hospedaje estático, donde no se usa .NET para suministrar la aplicación Blazor. Esta estrategia se trata en la sección Implementación independiente, que incluye información sobre cómo hospedar una aplicación Blazor WebAssembly como una subaplicación de IIS.
- Una aplicación de ASP.NET Core hospeda varias aplicaciones Blazor WebAssembly. Para más información, consulte Varias aplicaciones de ASP.NET Core Blazor WebAssembly hospedadas.
Hospedaje de subdominios e IIS
El hospedaje de subdominios no requiere una configuración especial de la aplicación. No es necesario configurar la ruta de acceso base de la aplicación (la etiqueta <base>
en wwwroot/index.html
) para hospedar la aplicación en un subdominio.
El hospedaje de sub-aplicaciones en IIS requiere que usted establezca la ruta base de la aplicación. Para obtener más información y vínculos cruzados para obtener instrucciones adicionales sobre el hospedaje de aplicaciones secundarias de IIS, consulte Hospedaje e implementación de ASP.NET Core Blazor.
Reducir el tamaño máximo del montón para algunos exploradores de dispositivo móvil
Al compilar una aplicación Blazor que se ejecuta en el cliente (proyecto .Client
de una app Blazor Web App o Blazor WebAssembly independiente) y tiene como destino exploradores de dispositivos móviles, especialmente Safari en iOS, la disminución de la memoria máxima de la aplicación con la propiedad MSBuild EmccMaximumHeapSize
puede ser necesaria. El valor predeterminado es 2 147 483 648 bytes, que puede ser demasiado grande y provocar el bloqueo de la aplicación si intenta asignar más memoria y el navegador no se la concede. En el ejemplo siguiente se establece el valor en 268 435 456 bytes en el archivo Program
:
Al compilar una aplicación Blazor WebAssembly que tenga como destino exploradores de dispositivos móviles, especialmente Safari en iOS, es posible que sea necesario reducir la memoria máxima de la aplicación con la propiedad MSBuild EmccMaximumHeapSize
. El valor predeterminado es 2 147 483 648 bytes, que puede ser demasiado grande y provocar el bloqueo de la aplicación si intenta asignar más memoria y el navegador no se la concede. En el ejemplo siguiente se establece el valor en 268 435 456 bytes en el archivo Program
:
<EmccMaximumHeapSize>268435456</EmccMaximumHeapSize>
Para obtener más información sobre las propiedades y destinos de MSBuild de Mono/WebAssembly, consulte WasmApp.Common.targets
(repositorio de GitHub dotnet/runtime
).
Formato de empaquetado de Webcil para ensamblados .NET
Webcil es un formato de empaquetado compatible con la web para ensamblados .NET diseñados para permitir el uso de Blazor WebAssembly en entornos de red restrictivos. Los archivos Webcil usan un contenedor WebAssembly estándar, donde los ensamblados se implementan como archivos WebAssembly que usan la extensión de archivo estándar .wasm
.
Webcil es el formato de empaquetado predeterminado al publicar una aplicación Blazor WebAssembly. Para deshabilitar el uso de Webcil, establezca la siguiente propiedad MSBuild en el archivo de proyecto de la aplicación:
<PropertyGroup>
<WasmEnableWebcil>false</WasmEnableWebcil>
</PropertyGroup>
Personalización de la carga de los recursos de arranque
Personalice la forma en que se cargan los recursos de arranque mediante la API loadBootResource
. Para obtener más información, vea Inicio de Blazor de ASP.NET Core.
Compresión
Cuando se publica una aplicación Blazor WebAssembly, la salida se comprime estáticamente durante la publicación para reducir el tamaño de la aplicación y acabar con la necesidad de compresión en tiempo de ejecución. Se usan los algoritmos de compresión siguientes:
Blazor se basa en el host para proporcionar los archivos comprimidos adecuados. Al hospedar una aplicación independiente Blazor WebAssembly, puede que sea necesario realizar trabajo adicional para garantizar que se proporcionan los archivos comprimidos estáticamente:
Blazor se basa en el host para proporcionar los archivos comprimidos adecuados. Cuando se usa un proyecto Blazor WebAssemblyhospedado de ASP.NET Core, el proyecto host tiene capacidad para realizar la negociación de contenido y proporcionar los archivos comprimidos estáticamente. Al hospedar una aplicación independiente Blazor WebAssembly, puede que sea necesario realizar trabajo adicional para garantizar que se proporcionan los archivos comprimidos estáticamente:
- Para ver la configuración de compresión de
web.config
de IIS, vea la sección IIS: compresión Brotli y Gzip. - Al hospedar en soluciones de hospedaje estáticas que no admiten la negociación de contenido de archivos comprimidos estáticamente, considere la posibilidad de configurar la aplicación para capturar y descodificar archivos comprimidos Brotli:
Obtenga el descodificador Brotli de JavaScript del repositorio de GitHub google/brotli
. El archivo del descodificador minificado se llama decode.min.js
y se encuentra en la carpeta js
del repositorio.
Nota
Si se produce un error en la versión minificada del script decode.js
(decode.min.js
), en su lugar, pruebe a usar la versión no minificada (decode.js
).
Actualice la aplicación para que use el descodificador.
En el archivo wwwroot/index.html
, establezca autostart
en false
en la etiqueta Blazor de <script>
:
<script src="_framework/blazor.webassembly.js" autostart="false"></script>
Después de la etiqueta <script>
de Blazor y antes de la etiqueta de cierre </body>
, agregue el siguiente bloque <script>
de código de JavaScript.
Blazor Web App:
<script type="module">
import { BrotliDecode } from './decode.min.js';
Blazor.start({
webAssembly: {
loadBootResource: function (type, name, defaultUri, integrity) {
if (type !== 'dotnetjs' && location.hostname !== 'localhost' && type !== 'configuration' && type !== 'manifest') {
return (async function () {
const response = await fetch(defaultUri + '.br', { cache: 'no-cache' });
if (!response.ok) {
throw new Error(response.statusText);
}
const originalResponseBuffer = await response.arrayBuffer();
const originalResponseArray = new Int8Array(originalResponseBuffer);
const decompressedResponseArray = BrotliDecode(originalResponseArray);
const contentType = type ===
'dotnetwasm' ? 'application/wasm' : 'application/octet-stream';
return new Response(decompressedResponseArray,
{ headers: { 'content-type': contentType } });
})();
}
}
}
});
</script>
Blazor WebAssembly independiente:
<script type="module">
import { BrotliDecode } from './decode.min.js';
Blazor.start({
loadBootResource: function (type, name, defaultUri, integrity) {
if (type !== 'dotnetjs' && location.hostname !== 'localhost' && type !== 'configuration') {
return (async function () {
const response = await fetch(defaultUri + '.br', { cache: 'no-cache' });
if (!response.ok) {
throw new Error(response.statusText);
}
const originalResponseBuffer = await response.arrayBuffer();
const originalResponseArray = new Int8Array(originalResponseBuffer);
const decompressedResponseArray = BrotliDecode(originalResponseArray);
const contentType = type ===
'dotnetwasm' ? 'application/wasm' : 'application/octet-stream';
return new Response(decompressedResponseArray,
{ headers: { 'content-type': contentType } });
})();
}
}
});
</script>
Para obtener más información sobre la carga de los recursos de arranque, vea Inicio de Blazor de ASP.NET Core.
Para deshabilitar la compresión, agregue la propiedad CompressionEnabled
de MSBuild al archivo del proyecto de la aplicación y establezca el valor en false
:
<PropertyGroup>
<CompressionEnabled>false</CompressionEnabled>
</PropertyGroup>
La propiedad CompressionEnabled
se puede pasar al comando dotnet publish
con la sintaxis siguiente en un shell de comandos:
dotnet publish -p:CompressionEnabled=false
Para deshabilitar la compresión, agregue la propiedad BlazorEnableCompression
de MSBuild al archivo del proyecto de la aplicación y establezca el valor en false
:
<PropertyGroup>
<BlazorEnableCompression>false</BlazorEnableCompression>
</PropertyGroup>
La propiedad BlazorEnableCompression
se puede pasar al comando dotnet publish
con la sintaxis siguiente en un shell de comandos:
dotnet publish -p:BlazorEnableCompression=false
Reescritura de las URL para conseguir un enrutamiento correcto
Enrutar las solicitudes de los componentes de página de una aplicación Blazor WebAssembly no es tan sencillo como enrutar las solicitudes de una aplicación Blazor Server. Imagine que tiene una aplicación Blazor WebAssembly con dos componentes:
Main.razor
: se carga en la raíz de la aplicación y contiene un vínculo al componenteAbout
(href="About"
).About.razor
: componenteAbout
.
Cuando se solicita el documento predeterminado de la aplicación mediante la barra de direcciones del explorador (por ejemplo, https://www.contoso.com/
):
- El explorador realiza una solicitud.
- Se devuelve la página predeterminada, que suele ser
index.html
. index.html
arranca la aplicación.- Router carga el componente y se representa el componente Razor
Main
.
En la página principal, la selección del vínculo al componente About
funciona en el cliente porque el enrutador de Blazor impide que el explorador haga una solicitud en Internet a www.contoso.com
sobre About
y presenta el propio componente About
representado. Todas las solicitudes de puntos de conexión internos dentro de la aplicación Blazor WebAssembly funcionan del mismo modo: Las solicitudes no desencadenan solicitudes basadas en el explorador a recursos hospedados en el servidor en Internet. El enrutador controla las solicitudes de forma interna.
Si se realiza una solicitud mediante la barra de direcciones del explorador para www.contoso.com/About
, se produce un error. Este recurso no existe en el host de Internet de la aplicación, por lo que se devuelve una respuesta 404 No encontrado.
Dado que los exploradores solicitan páginas del lado cliente a hosts basados en Internet, los servidores web y los servicios de hospedaje deben reescribir todas las solicitudes de recursos que no estén físicamente en el servidor a la página index.html
. Cuando se devuelve index.html
, el enrutador Blazor de la aplicación se hace cargo y responde con el recurso correcto.
Al implementar en un servidor IIS, puede usar el módulo URL Rewrite con el archivo web.config
publicado de la aplicación. Para más información, consulte la sección sobre IIS.
Implementación hospedada con ASP.NET Core
Una implementación hospedada se encarga de suministrar la aplicación Blazor WebAssembly a los exploradores desde una aplicación ASP.NET Core que se ejecuta en un servidor web.
La aplicación cliente de Blazor WebAssembly se publica en la carpeta /bin/Release/{TARGET FRAMEWORK}/publish/wwwroot
de la aplicación de servidor, junto con cualquier otro recurso web estático de la aplicación de servidor. Las dos aplicaciones se implementan juntas. Se requiere un servidor web que pueda hospedar una aplicación ASP.NET Core. En el caso de una implementación hospedada, Visual Studio incluye la plantilla de proyecto Aplicación de Blazor WebAssembly (plantilla blazorwasm
si se usa el comando dotnet new
) con la opción Hosted
seleccionada (-ho|--hosted
si se usa el comando dotnet new
).
Para obtener más información, consulta los siguientes artículos.
- Implementación y hospedaje de aplicaciones de ASP.NET Core: Implementación y hospedaje de ASP.NET Core
- Implementación en Azure App Service: Publicar una aplicación de ASP.NET Core en Azure con Visual Studio
- Plantillas de proyecto de Blazor: Estructura del proyecto de Blazor de ASP.NET Core
Implementación hospedada de un archivo ejecutable dependiente de la plataforma para una plataforma específica
Para implementar una aplicación Blazor WebAssembly hospedada como un ejecutable dependiente del marco para una plataforma específica (no independiente), sigue estas instrucciones basadas en las herramientas que se usan.
Visual Studio
Se configura una implementación independiente para un perfil de publicación generado (.pubxml
). Comprueba que el perfil de publicación del proyecto Server contiene la <SelfContained>
propiedad MSBuild establecida en false
.
En el archivo de perfil de publicación .pubxml
de la carpeta Properties
del proyecto Server:
<SelfContained>false</SelfContained>
Establece el identificador de tiempo de ejecución (RID) mediante el valor de Tiempo de ejecución de destino en el área Configuración de la interfaz de usuario de Publicación, que genera la propiedad MSBuild <RuntimeIdentifier>
en el perfil de publicación:
<RuntimeIdentifier>{RID}</RuntimeIdentifier>
En la configuración anterior, el marcador de posición {RID}
es el identificador de tiempo de ejecución (RID).
Publica el proyecto Server en la configuración de Versión.
Nota
Es posible publicar una aplicación con la configuración del perfil de publicación mediante la CLI de .NET pasando /p:PublishProfile={PROFILE}
al comando dotnet publish
, donde el marcador de posición {PROFILE}
es el perfil. Para obtener más información, consulta las secciones Publicar los perfiles y Ejemplo de publicación de carpetas en el artículo Perfiles de publicación (.pubxml) de Visual Studio para la implementación de aplicaciones ASP.NET Core. Si pasas el RID en el comando dotnet publish
y no en el perfil de publicación, usa la propiedad MSBuild (/p:RuntimeIdentifier
) con el comando, no con la opción -r|--runtime
.
CLI de .NET
Configura una implementación independiente colocando la propiedad MSBuild <SelfContained>
en un <PropertyGroup>
en el archivo de proyecto del proyecto Server establecido en false
:
<SelfContained>false</SelfContained>
Importante
La propiedad SelfContained
debe colocarse en el archivo de proyecto del proyecto Server. La propiedad no se puede establecer correctamente con el comando dotnet publish
mediante la opción --no-self-contained
o la propiedad MSBuild /p:SelfContained=false
.
Establece el identificador en tiempo de ejecución (RID) mediante cualquiera de los métodos siguientes:
Opción 1: Establece el RID en un
<PropertyGroup>
en el archivo de proyecto del proyecto Server:<RuntimeIdentifier>{RID}</RuntimeIdentifier>
En la configuración anterior, el marcador de posición
{RID}
es el identificador de tiempo de ejecución (RID).Publica la aplicación en la configuración de versión del proyecto Server:
dotnet publish -c Release
Opción 2: Pasa el RID en el comando
dotnet publish
como la propiedad de MSBuild (/p:RuntimeIdentifier
), no con la opción-r|--runtime
:dotnet publish -c Release /p:RuntimeIdentifier={RID}
En el comando anterior, el marcador de posición
{RID}
es el identificador de tiempo de ejecución (RID).
Para obtener más información, consulta los siguientes artículos.
Implementación hospedada con varias aplicaciones Blazor WebAssembly
Para obtener más información, consulta Varias aplicaciones de ASP.NET Core Blazor WebAssembly hospedadas.
Implementación independiente
Una implementación independiente suministra la aplicación Blazor WebAssembly como un conjunto de archivos estáticos que los clientes solicitan directamente. Cualquier servidor de archivos estático es capaz de suministrar la aplicación Blazor.
Los recursos de implementación independientes se publican en la carpeta /bin/Release/{TARGET FRAMEWORK}/publish/wwwroot
o bin\Release\{TARGET FRAMEWORK}\browser-wasm\publish\
(en función de la versión del SDK de .NET en uso), donde el marcador de posición {TARGET FRAMEWORK}
es el marco de destino.
Azure App Service
Las aplicaciones Blazor WebAssembly se pueden implementar en Azure App Services en Windows, que hospeda la aplicación en IIS.
Actualmente no se admite la implementación de una aplicación Blazor WebAssembly independiente en Azure App Service para Linux. Se recomienda hospedar una aplicación independiente Blazor WebAssembly mediante Azure Static Web Apps, que admite este escenario.
Azure Static Web Apps
Usa uno de los enfoques siguientes para implementar una aplicación Blazor WebAssembly en Azure Static Web Apps:
- Implementación desde Visual Studio
- Implementación desde Visual Studio Code
- Implementación desde GitHub
Implementación desde Visual Studio
Para realizar la implementación desde Visual Studio, crea un perfil de publicación para Azure Static Web Apps:
Guarda cualquier trabajo no guardado en el proyecto, ya que es posible que se requiera un reinicio de Visual Studio durante el proceso.
En la interfaz de usuario de publicación de Visual Studio, selecciona Destino>Azure>Destino específico>Azure Static Web Apps para crear un perfil de publicación.
Si el componente Azure WebJobs Tools para Visual Studio no está instalado, aparece un mensaje para instalar el componente ASP.NET y desarrollo web. Sigue las indicaciones para instalar las herramientas mediante el Instalador de Visual Studio. Visual Studio se cierra y vuelve a abrirse automáticamente al instalar las herramientas. Una vez instaladas las herramientas, comienza en el primer paso para crear el perfil de publicación.
En la configuración del perfil de publicación, proporciona el nombre de la suscripción. Selecciona una instancia existente o selecciona Crear una nueva instancia. Al crear una nueva instancia en la interfaz de usuario Crear aplicación web estática de Azure Portal, establezca Detalles de la implementación>Origen en Otro. Espera a que la implementación se complete en Azure Portal antes de continuar.
En la configuración del perfil de publicación, selecciona la instancia de Azure Static Web Apps del grupo de recursos de la instancia. Selecciona Finalizar para crear el perfil de publicación. Si Visual Studio solicita que instale la CLI de Static Web Apps (SWA), instala la CLI siguiendo las indicaciones. La CLI de SWA requiere NPM/Node.js (documentación de Visual Studio).
Una vez creado el perfil de publicación, implementa la aplicación en la instancia de Azure Static Web Apps mediante el perfil de publicación seleccionando el botón Publicar.
Implementación desde Visual Studio Code
Para implementar desde Visual Studio Code, consulta Inicio rápido: creación de tu primer sitio estático con Azure Static Web Apps.
Implementación desde GitHub
Para realizar la implementación desde un repositorio de GitHub, consulta Tutorial: Creación de una aplicación web estática con Blazor en Azure Static Web Apps.
IIS
IIS es un servidor de archivos estáticos compatible con las aplicaciones Blazor. Para configurar IIS para hospedar Blazor, consulta Compilación de un sitio web estático en IIS.
Los recursos publicados se crean en la carpeta /bin/Release/{TARGET FRAMEWORK}/publish
o bin\Release\{TARGET FRAMEWORK}\browser-wasm\publish
, en función de la versión del SDK que se use y de donde el marcador de posición {TARGET FRAMEWORK}
sea la plataforma de destino. Hospeda el contenido de la carpeta publish
en el servidor web o el servicio de hospedaje.
web.config
Cuando se publica un proyecto de Blazor, se crea un archivo web.config
con la siguiente configuración de IIS:
- Tipos MIME
- Se habilita la compresión HTTP de los siguientes tipos MIME:
application/octet-stream
application/wasm
- Se establecen reglas del módulo URL Rewrite:
- Proporciona el subdirectorio donde residen los recursos estáticos de la aplicación (
wwwroot/{PATH REQUESTED}
). - Crea el enrutamiento de reserva de SPA para que las solicitudes de recursos que no sean archivos se redirijan al documento predeterminado de la aplicación en su carpeta de recursos estáticos (
wwwroot/index.html
).
- Proporciona el subdirectorio donde residen los recursos estáticos de la aplicación (
Uso de una web.config
personalizada
Para usar un archivo web.config
personalizado:
- Coloca el archivo
web.config
personalizado en la carpeta raíz del proyecto. - Publica el proyecto. Para obtener más información, consulta Hospedaje e implementación en ASP.NET Core Blazor.
- Coloca el archivo
web.config
personalizado en la carpeta raíz del proyecto. En el caso de una Blazor WebAssemblysolución hospedada, coloca el archivo en la carpeta del proyecto de Server. - Publica el proyecto. Para una solución de Blazor WebAssembly hospedada, publica la solución desde el proyecto Server. Para obtener más información, consulta Hospedaje e implementación en ASP.NET Core Blazor.
Si la generación o transformación web.config
del SDK durante la publicación no mueve el archivo a recursos publicados en la carpeta publish
o modifica la configuración personalizada en el archivo personalizado web.config
, usa cualquiera de los enfoques siguientes según sea necesario para tomar el control total del proceso:
Si el SDK no genera el archivo, por ejemplo, en una aplicación independiente Blazor WebAssembly en
/bin/Release/{TARGET FRAMEWORK}/publish/wwwroot
obin\Release\{TARGET FRAMEWORK}\browser-wasm\publish
, en función de la versión del SDK que se use y de donde el marcador de posición{TARGET FRAMEWORK}
sea la plataforma de destino, establece la propiedad<PublishIISAssets>
entrue
en el archivo de proyecto (.csproj
). Normalmente, para las aplicaciones WebAssembly independientes, esta es la única configuración necesaria para mover un archivo personalizadoweb.config
y evitar la transformación del archivo por parte del SDK.<PropertyGroup> <PublishIISAssets>true</PublishIISAssets> </PropertyGroup>
Deshabilita la transformación
web.config
del SDK en el archivo de proyecto (.csproj
):<PropertyGroup> <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled> </PropertyGroup>
Agrega un destino personalizado al archivo de proyecto (
.csproj
) para mover un archivo personalizadoweb.config
. En el ejemplo siguiente, el desarrollador coloca el archivo personalizadoweb.config
en la raíz del proyecto. Si el archivoweb.config
reside en otro lugar, especifica la ruta de acceso al archivo enSourceFiles
. En el ejemplo siguiente se especifica la carpetapublish
con$(PublishDir)
, pero se proporciona una ruta de acceso aDestinationFolder
para una ubicación de salida personalizada.<Target Name="CopyWebConfig" AfterTargets="Publish"> <Copy SourceFiles="web.config" DestinationFolder="$(PublishDir)" /> </Target>
Instalación del módulo URL Rewrite
El módulo URL Rewrite es necesario para reescribir las URL. El módulo no se instala de forma predeterminada y no está disponible para instalar como una característica de servicio de rol del servidor web (IIS). El módulo se debe descargar desde el sitio web de IIS. Usa el instalador de plataforma web para instalar el módulo:
- De forma local, ve a la página de descargas del módulo reescritura de URL. En el caso de la versión en inglés, seleccione WebPI para descargar el instalador de WebPI. En el caso de otros idiomas, seleccione la arquitectura adecuada del servidor (x86/x64) para descargar el instalador.
- Copie el instalador en el servidor. Ejecute el instalador. Haga clic en el botón Instalar y acepte los términos de licencia. No es necesario reiniciar el servidor al finalizar la instalación.
Configuración del sitio web
Configure la ruta de acceso física del sitio web a la carpeta de la aplicación. La carpeta contiene:
- El archivo
web.config
que usa IIS para configurar el sitio web, incluidas las reglas de redireccionamiento y los tipos de contenido de archivo necesarios. - La carpeta de recursos estáticos de la aplicación.
Hospedaje como subaplicación de IIS
Si una aplicación independiente se hospeda como una subaplicación de IIS, realice una de las siguientes acciones:
Deshabilite el controlador del módulo de ASP.NET Core heredado.
Para quitar el controlador del archivo
web.config
publicado de la aplicación Blazor, agregue una sección<handlers>
a la sección<system.webServer>
del archivo:<handlers> <remove name="aspNetCore" /> </handlers>
Deshabilite la herencia de la sección
<system.webServer>
de la aplicación raíz (principal) mediante un elemento<location>
coninheritInChildApplications
establecido enfalse
:<?xml version="1.0" encoding="utf-8"?> <configuration> <location path="." inheritInChildApplications="false"> <system.webServer> <handlers> <add name="aspNetCore" ... /> </handlers> <aspNetCore ... /> </system.webServer> </location> </configuration>
Nota
Deshabilitar la herencia de la sección
<system.webServer>
de la aplicación raíz (primaria) es la configuración predeterminada para las aplicaciones publicadas mediante el SDK de .NET.
Además de configurarse la ruta de acceso base de la aplicación, se quita el controlador o se deshabilita la herencia. En el archivo index.html
de la aplicación, establezca la ruta de acceso base de la aplicación en el alias de IIS que ha usado al configurar la subaplicación en IIS.
Configure la ruta de acceso base de la aplicación siguiendo las indicaciones del artículo Hospedar e implementar ASP.NET Core Blazor.
Compresión Brotli y Gzip
Esta sección solo se aplica a aplicaciones Blazor WebAssembly independientes.
Esta sección solo se aplica a aplicaciones Blazor WebAssembly independientes. Las aplicaciones hospedadas de Blazor usan un archivo web.config
de la aplicación ASP.NET Core predeterminado, no el archivo vinculado en esta sección.
IIS se puede configurar a través de web.config
para dar servicio a recursos de Blazor comprimidos con Brotli o Gzip para aplicaciones de Blazor WebAssembly independientes. Para ver un archivo de configuración de ejemplo, consulte web.config
.
Podría ser necesaria una configuración adicional del archivo web.config
de ejemplo en los escenarios siguientes:
- La especificación de la aplicación requiere cualquiera de las siguientes opciones:
- Servir archivos comprimidos que no están configurados por el archivo
web.config
de ejemplo. - Servir archivos comprimidos configurados por el archivo
web.config
de ejemplo en un formato sin comprimir.
- Servir archivos comprimidos que no están configurados por el archivo
- La configuración de IIS del servidor (por ejemplo,
applicationHost.config
) proporciona valores predeterminados de IIS de nivel de servidor. En función de la configuración de nivel de servidor, es posible que la aplicación requiera una configuración de IIS diferente de la que contiene el archivo deweb.config
de ejemplo.
Para más información sobre los archivos personalizados web.config
, consulte la sección Uso de web.config
personalizado.
Solución de problemas
Si se recibe un error 500 Error interno del servidor y el administrador de IIS produce errores al intentar acceder a la configuración del sitio web, confirme que el módulo URL Rewrite está instalado. Si no lo está, IIS no puede analizar el archivo web.config
. Esto impide que el Administrador de IIS cargue la configuración del sitio web y que el sitio web suministre los archivos estáticos de Blazor.
Para obtener más información sobre la solución de problemas de implementaciones en IIS, consulte Solución de ASP.NET Core {1}en Azure App Service e IIS.
Azure Storage
El hospedaje de archivos estáticos de Azure Storage permite el hospedaje de aplicaciones Blazor sin servidor. Se admiten nombres de dominio personalizados, Azure Content Delivery Network (CDN) y HTTPS.
Cuando el servicio de blob está habilitado para el hospedaje de sitios web estáticos en una cuenta de almacenamiento:
- Establece el nombre de documento de índice en
index.html
. - Establece la ruta de acceso del documento de error en
index.html
. Los componentes Razor y otros puntos de conexión que no son de archivo no residen en las rutas de acceso físicas del contenido estático almacenado por el servicio de blob. Cuando se recibe una solicitud de uno de estos recursos que debe controlar el enrutador de Blazor, el error 404 - No encontrado generado por el servicio de blob enruta la solicitud a la ruta de acceso del documento de error. Se devuelve el blobindex.html
, y el enrutador de Blazor carga y procesa la ruta de acceso.
Si los archivos no se cargan en tiempo de ejecución debido a tipos MIME inadecuados en los encabezados Content-Type
de los archivos, haga algunas de las acciones siguientes:
Configure las herramientas para establecer los tipos MIME correctos (encabezados
Content-Type
) cuando se implementen los archivos.Cambie los tipos MIME (encabezados
Content-Type
) de los archivos una vez que se implementa la aplicación.En cada archivo del Explorador de Storage (Azure Portal) haga lo siguiente:
- Haga clic con el botón derecho en el archivo y seleccione Propiedades.
- Establezca el valor de ContentType y seleccione el botón Guardar.
Para más información, consulte Hospedaje de sitios web estáticos en Azure Storage.
Nginx
El siguiente archivo nginx.conf
se ha simplificado para mostrar cómo hay que configurar Nginx para enviar el archivo index.html
siempre que no pueda encontrar un archivo correspondiente en el disco.
events { }
http {
server {
listen 80;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html =404;
}
}
}
Al establecer el límite de velocidad de ráfaga de NGINX con limit_req
, las aplicaciones de Blazor WebAssembly pueden requerir un valor de parámetro burst
grande para acomodar el número relativamente elevado de solicitudes realizadas por una aplicación. Inicialmente, establezca el valor en al menos 60:
http {
server {
...
location / {
...
limit_req zone=one burst=60 nodelay;
}
}
}
Aumente el valor si las herramientas de desarrollo del explorador o la herramienta de tráfico de red indican que las solicitudes reciben un código de estado 503: Servicio no disponible.
Para obtener más información sobre la configuración del servidor web de producción de Nginx, consulte Creating NGINX Plus and NGINX Configuration Files (Creación de archivos de configuración de NGINX y NGINX Plus).
Apache
Para implementar una aplicación de Blazor WebAssembly en Apache:
Cree el archivo de configuración de Apache. El siguiente ejemplo es un archivo de configuración simplificado (
blazorapp.config
):<VirtualHost *:80> ServerName www.example.com ServerAlias *.example.com DocumentRoot "/var/www/blazorapp" ErrorDocument 404 /index.html AddType application/wasm .wasm <Directory "/var/www/blazorapp"> Options -Indexes AllowOverride None </Directory> <IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE application/octet-stream AddOutputFilterByType DEFLATE application/wasm <IfModule mod_setenvif.c> BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4.0[678] no-gzip BrowserMatch bMSIE !no-gzip !gzip-only-text/html </IfModule> </IfModule> ErrorLog /var/log/httpd/blazorapp-error.log CustomLog /var/log/httpd/blazorapp-access.log common </VirtualHost>
Cree el archivo de configuración de Apache. El siguiente ejemplo es un archivo de configuración simplificado (
blazorapp.config
):<VirtualHost *:80> ServerName www.example.com ServerAlias *.example.com DocumentRoot "/var/www/blazorapp" ErrorDocument 404 /index.html AddType application/wasm .wasm AddType application/octet-stream .dll <Directory "/var/www/blazorapp"> Options -Indexes AllowOverride None </Directory> <IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE application/octet-stream AddOutputFilterByType DEFLATE application/wasm <IfModule mod_setenvif.c> BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4.0[678] no-gzip BrowserMatch bMSIE !no-gzip !gzip-only-text/html </IfModule> </IfModule> ErrorLog /var/log/httpd/blazorapp-error.log CustomLog /var/log/httpd/blazorapp-access.log common </VirtualHost>
Coloque el archivo de configuración de Apache en el directorio
/etc/httpd/conf.d/
.Coloque los recursos publicados de la aplicación (
/bin/Release/{TARGET FRAMEWORK}/publish/wwwroot
, donde el marcador de posición{TARGET FRAMEWORK}
es el marco de destino) en el directorio/var/www/blazorapp
(la ubicación especificada aDocumentRoot
en el archivo de configuración).Reinicie el servicio de Apache.
Para obtener más información, vea mod_mime
y mod_deflate
.
GitHub Pages
La acción predeterminada de GitHub, que implementa páginas, omite la implementación de carpetas que empiezan por un carácter de subrayado como, por ejemplo, la carpeta_framework
. Para implementar carpetas que empiezan por el carácter de subrayado, añada un archivo vacío .nojekyll
a la rama de Git.
Git trata los archivos de JavaScript (JS) como, por ejemplo, blazor.webassembly.js
, como texto y convierte los finales de línea CRLF (retorno de carro-salto de línea) a LF (salto de línea) en la canalización de implementación. Estos cambios en los archivos JS generan hashes de archivo distintos de los que Blazor envía al cliente en el archivo blazor.boot.json
. Las discordancias dan lugar a errores de comprobación de integridad en el cliente. Un enfoque para resolver este problema es añadir un archivo .gitattributes
con la línea *.js binary
antes de añadir los recursos de la aplicación a la rama de Git. La línea *.js binary
configura Git para que trate los archivos JS como archivos binarios, lo que evita su procesamiento en la canalización de implementación. Los hashes de los archivos no procesados coincidirán con las entradas del archivo blazor.boot.json
y las comprobaciones de integridad del lado cliente se pasarán. Para obtener más información, consulte ASP.NET Core Blazor WebAssembly Runtime de .NET y el almacenamiento en caché de lote de aplicaciones.
Para controlar las reescrituras de URL, agregue un archivo wwwroot/404.html
con un script que controle el redireccionamiento de la solicitud a la página index.html
. Para obtener un ejemplo, consulte el repositorio de GitHub SteveSandersonMS/BlazorOnGitHubPages
:
Si usa un sitio de proyecto en lugar de un sitio de la organización, actualice la etiqueta <base>
en wwwroot/index.html
. Defina el valor del atributo href
con el nombre del repositorio de GitHub con una barra diagonal final (por ejemplo, /my-repository/
). En el repositorio de GitHub SteveSandersonMS/BlazorOnGitHubPages
, el elemento href
base se actualiza cuando el archivo de configuración .github/workflows/main.yml
realiza la publicación.
Nota:
El repositorio de GitHub SteveSandersonMS/BlazorOnGitHubPages
no es propiedad de .NET Foundation o Microsoft, ni tampoco se encargan de su mantenimiento ni es compatible con ellos.
Independiente con Docker
Una aplicación independiente Blazor WebAssembly se publica como un conjunto de archivos estáticos que hospeda un servidor de archivos estáticos.
Para hospedar la aplicación en Docker:
- Elija un contenedor de Docker con compatibilidad con el servidor web, como Ngnix o Apache.
- Copie los recursos de la carpeta
publish
en una carpeta de ubicación definida en el servidor web para atender archivos estáticos. - Aplique la configuración adicional según sea necesario para atender la aplicación Blazor WebAssembly.
Para ver documentación adicional, consulte los siguientes recursos:
- Sección Nginx o sección Apache de este artículo.
- Documentación de Docker.
Valores de configuración de host
Las aplicaciones Blazor WebAssembly pueden aceptar los siguientes valores de configuración de host como argumentos de línea de comandos en tiempo de ejecución en el entorno de desarrollo.
Raíz del contenido
El argumento --contentroot
establece la ruta de acceso absoluta al directorio que incluye los archivos de contenido de la aplicación (raíz del contenido). En los ejemplos siguientes, /content-root-path
es la ruta de acceso raíz del contenido de la aplicación.
Pase el argumento al ejecutar la aplicación de forma local en un símbolo del sistema. En el directorio de la aplicación, ejecute lo siguiente:
dotnet watch --contentroot=/content-root-path
Agregue una entrada al archivo
launchSettings.json
de la aplicación en el perfil IIS Express. Esta configuración se utiliza cuando se ejecuta la aplicación mediante el depurador de Visual Studio y desde un símbolo del sistema condotnet watch
(odotnet run
)."commandLineArgs": "--contentroot=/content-root-path"
En Visual Studio, especifique el argumento en Propiedades>Depuración>Argumentos de la aplicación. Al establecer el argumento en la página de propiedades de Visual Studio, se agrega el argumento al archivo
launchSettings.json
.--contentroot=/content-root-path
Ruta de acceso base
El argumento --pathbase
establece la ruta de acceso base de la aplicación para una aplicación que se ejecuta localmente con una ruta de acceso de URL relativa que no es raíz (el valor href
de la etiqueta <base>
se establece en una ruta de acceso que no sea /
para ensayo y producción). En los ejemplos siguientes, /relative-URL-path
es la ruta de acceso base de la aplicación. Para obtener más información, vea Ruta de acceso base de la aplicación.
Importante
A diferencia de la ruta de acceso proporcionada al valor href
de la etiqueta <base>
, no incluya una barra diagonal final (/
) al pasar el valor del argumento --pathbase
. Si se proporciona la ruta de acceso base de la aplicación en la etiqueta <base>
como <base href="/CoolApp/">
(se incluye una barra diagonal final), se pasa el valor del argumento de línea de comandos como --pathbase=/CoolApp
(sin barra diagonal final).
Pase el argumento al ejecutar la aplicación de forma local en un símbolo del sistema. En el directorio de la aplicación, ejecute lo siguiente:
dotnet watch --pathbase=/relative-URL-path
Agregue una entrada al archivo
launchSettings.json
de la aplicación en el perfil IIS Express. Esta configuración se utiliza cuando se ejecuta la aplicación mediante el depurador de Visual Studio y desde un símbolo del sistema condotnet watch
(odotnet run
)."commandLineArgs": "--pathbase=/relative-URL-path"
En Visual Studio, especifique el argumento en Propiedades>Depuración>Argumentos de la aplicación. Al establecer el argumento en la página de propiedades de Visual Studio, se agrega el argumento al archivo
launchSettings.json
.--pathbase=/relative-URL-path
Direcciones URL
El argumento --urls
establece las direcciones IP o las direcciones de host con los puertos y protocolos en los que escuchar las solicitudes.
Pase el argumento al ejecutar la aplicación de forma local en un símbolo del sistema. En el directorio de la aplicación, ejecute lo siguiente:
dotnet watch --urls=http://127.0.0.1:0
Agregue una entrada al archivo
launchSettings.json
de la aplicación en el perfil IIS Express. Esta configuración se utiliza cuando se ejecuta la aplicación mediante el depurador de Visual Studio y desde un símbolo del sistema condotnet watch
(odotnet run
)."commandLineArgs": "--urls=http://127.0.0.1:0"
En Visual Studio, especifique el argumento en Propiedades>Depuración>Argumentos de la aplicación. Al establecer el argumento en la página de propiedades de Visual Studio, se agrega el argumento al archivo
launchSettings.json
.--urls=http://127.0.0.1:0
Implementación hospedada en Linux (Nginx)
Configure la aplicación con ForwardedHeadersOptions para reenviar los encabezados X-Forwarded-For
y X-Forwarded-Proto
siguiendo las instrucciones de Configuración de ASP.NET Core para trabajar con servidores proxy y equilibradores de carga.
Para más información sobre cómo establecer la ruta base de la aplicación, incluida la configuración de la ruta de la subaplicación, vea Hospedaje e implementación de ASP.NET Core Blazor.
Siga las instrucciones para obtener una aplicación SignalR de ASP.NET Core con los siguientes cambios:
Quite la configuración de almacenamiento en búfer de proxy (
proxy_buffering off;
) porque la configuración solo se aplica a los eventos enviados por el servidor (SSE), que no son relevantes para las interacciones cliente-servidor de la aplicación Blazor.Cambie la ruta de acceso de
location
de/hubroute
(location /hubroute { ... }
) a la ruta de acceso de la subaplicación/{PATH}
(location /{PATH} { ... }
), donde el marcador de posición{PATH}
es la ruta de acceso de la subaplicación.En el ejemplo siguiente se configura el servidor para una aplicación que responde a las solicitudes en la ruta de acceso raíz
/
:http { server { ... location / { ... } } }
En el ejemplo siguiente se configura la ruta de acceso de la aplicación de
/blazor
:http { server { ... location /blazor { ... } } }
Para obtener más información e instrucciones de configuración, vea los recursos siguientes:
- Hospedar ASP.NET Core en Linux con Nginx
- Documentación de Nginx:
- Desarrolladores en foros de soporte técnico que no son de Microsoft:
Configurar el recortador
Blazor realiza el recorte de lenguaje intermedio (IL) en cada compilación de lanzamiento para quitar el IL innecesario de los ensamblados de salida. Para más información, vea Configuración del recortador de ASP.NET Core Blazor.
Configurar el enlazador
Blazor realiza la vinculación de lenguaje intermedio (IL) en cada compilación de lanzamiento para quitar el IL innecesario de los ensamblados de salida. Para obtener más información, consulta Configuración del enlazador de ASP.NET Core Blazor.
Cambio de la extensión de nombre de archivo de los archivos DLL
Esta sección se aplica a ASP.NET Core 6.x y 7.x. En ASP.NET Core en .NET 8 o posterior, los ensamblados de .NET se implementan como archivos WebAssembly (.wasm
) mediante el formato de archivo Webcil. En ASP.NET Core en .NET 8 o posterior, esta sección solo se aplica si el formato de archivo Webcil se ha deshabilitado en el archivo de proyecto de la aplicación.
Si un firewall, un programa antivirus o un dispositivo de seguridad de red bloquea la trasmisión de los archivos de la biblioteca de vínculos dinámicos (DLL) de la aplicación (.dll
), puedes seguir las instrucciones de esta sección para cambiar las extensiones de nombre de archivo de los archivos DLL publicados de la aplicación.
Nota
Cambiar las extensiones de nombre de archivo de los archivos DLL de la aplicación quizá no resuelva el problema porque muchos sistemas de seguridad examinan el contenido de los archivos de la aplicación, no solo comprueban las extensiones de archivo.
Si buscas un enfoque más sólido en entornos que impiden la descarga y ejecución de archivos DLL, usa ASP.NET Core en .NET 8 o posterior, que empaqueta ensamblados .NET como archivos WebAssembly (.wasm
) mediante el formato de archivo Webcil. Para obtener más información, consulta la sección Formato de empaquetado de Webcil para ensamblados de .NET en una versión 8.0 o posterior de este artículo.
Existen enfoques de terceros para tratar este problema. Para obtener más información, consulta los recursos en Awesome Blazor.
Nota:
Cambiar las extensiones de nombre de archivo de los archivos DLL de la aplicación quizá no resuelva el problema porque muchos sistemas de seguridad examinan el contenido de los archivos de la aplicación, no solo comprueban las extensiones de archivo.
Para obtener un enfoque más sólido en entornos que bloquean la descarga y ejecución de archivos DLL, toma cualquiera de los enfoques siguientes:
- Usa ASP.NET Core en .NET 8 o posterior, que de forma predeterminada empaqueta ensamblados .NET como archivos WebAssembly (
.wasm
) con el formato de archivo Webcil. Para obtener más información, consulta la sección Formato de empaquetado de Webcil para ensamblados de .NET en una versión 8.0 o posterior de este artículo. - En ASP.NET Core en .NET 6 o posterior, usa un diseño de implementación personalizado.
Existen enfoques de terceros para tratar este problema. Para obtener más información, consulta los recursos en Awesome Blazor.
Después de publicar la aplicación, usa un script de shell o una canalización de compilación de DevOps para cambiar el nombre de los archivos .dll
a fin de usar otra extensión de archivo en el directorio de la salida publicada de la aplicación.
En los siguientes ejemplos:
- PowerShell (PS) se usa para actualizar las extensiones de archivo.
- Los archivos
.dll
cambian de nombre para usar la extensión de archivo.bin
de la línea de comandos. - Los archivos enumerados en el archivo
blazor.boot.json
publicado con una extensión de archivo.dll
se actualizan a la extensión de archivo.bin
. - Si los recursos de trabajo de servicio también están en uso, un comando de PowerShell actualiza los archivos
.dll
enumerados en el archivoservice-worker-assets.js
a la extensión de archivo.bin
.
Para usar una extensión de archivo distinta de .bin
, reemplace .bin
en los siguientes comandos por la extensión de archivo deseada.
En Windows:
dir {PATH} | rename-item -NewName { $_.name -replace ".dll\b",".bin" }
((Get-Content {PATH}\blazor.boot.json -Raw) -replace '.dll"','.bin"') | Set-Content {PATH}\blazor.boot.json
En el comando anterior, el marcador de posición {PATH}
es la ruta de acceso a la carpeta _framework
publicada (por ejemplo, .\bin\Release\net6.0\browser-wasm\publish\wwwroot\_framework
desde la carpeta raíz del proyecto).
Si los recursos de trabajo de servicio también están en uso, haz lo siguiente:
((Get-Content {PATH}\service-worker-assets.js -Raw) -replace '.dll"','.bin"') | Set-Content {PATH}\service-worker-assets.js
En el comando anterior, el marcador de posición {PATH}
es la ruta de acceso al archivo service-worker-assets.js
publicado.
En Linux o macOS:
for f in {PATH}/*; do mv "$f" "`echo $f | sed -e 's/\.dll/.bin/g'`"; done
sed -i 's/\.dll"/.bin"/g' {PATH}/blazor.boot.json
En el comando anterior, el marcador de posición {PATH}
es la ruta de acceso a la carpeta _framework
publicada (por ejemplo, .\bin\Release\net6.0\browser-wasm\publish\wwwroot\_framework
desde la carpeta raíz del proyecto).
Si los recursos de trabajo de servicio también están en uso, haz lo siguiente:
sed -i 's/\.dll"/.bin"/g' {PATH}/service-worker-assets.js
En el comando anterior, el marcador de posición {PATH}
es la ruta de acceso al archivo service-worker-assets.js
publicado.
Para dirigirte a los archivos comprimidos blazor.boot.json.gz
y blazor.boot.json.br
, adopta uno de los métodos siguientes:
- Quita los archivos comprimidos
blazor.boot.json.gz
yblazor.boot.json.br
. Con este enfoque, la compresión está deshabilitada. - Vuelve a comprimir el archivo
blazor.boot.json
actualizado.
La guía anterior del archivo blazor.boot.json
comprimido también se aplica cuando se usan recursos de trabajo de servicio. Quita o vuelve a comprimir service-worker-assets.js.br
y service-worker-assets.js.gz
. De lo contrario, las comprobaciones de integridad de los archivos producirán errores en el explorador.
En el siguiente ejemplo de Windows para .NET 6 se usa un script de PowerShell colocado en la raíz del proyecto. El siguiente script, que deshabilita la compresión, es la base para una modificación adicional si quiere volver a comprimir el archivo blazor.boot.json
.
ChangeDLLExtensions.ps1:
:
param([string]$filepath,[string]$tfm)
dir $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework | rename-item -NewName { $_.name -replace ".dll\b",".bin" }
((Get-Content $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\blazor.boot.json -Raw) -replace '.dll"','.bin"') | Set-Content $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\blazor.boot.json
Remove-Item $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\blazor.boot.json.gz
Remove-Item $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\blazor.boot.json.br
Si los recursos de trabajo de servicio también están en uso, agrega los siguientes comandos:
((Get-Content $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\service-worker-assets.js -Raw) -replace '.dll"','.bin"') | Set-Content $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\wwwroot\service-worker-assets.js
Remove-Item $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\wwwroot\service-worker-assets.js.gz
Remove-Item $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\wwwroot\service-worker-assets.js.br
En el archivo del proyecto, el script se ejecuta después de publicar la aplicación con la configuración de Release
:
<Target Name="ChangeDLLFileExtensions" AfterTargets="AfterPublish" Condition="'$(Configuration)'=='Release'">
<Exec Command="powershell.exe -command "& { .\ChangeDLLExtensions.ps1 '$(SolutionDir)' '$(TargetFramework)'}"" />
</Target>
Nota
Al cambiar el nombre y realizar la carga diferida de los mismos ensamblados, vea las instrucciones de Ensamblados de carga diferida en Blazor WebAssembly de ASP.NET Core.
Normalmente, el servidor de la aplicación requiere la configuración de recursos estáticos para servir los archivos con la extensión actualizada. Para una aplicación hospedada por IIS, agregue una entrada de asignación MIME (<mimeMap>
) para la nueva extensión de archivo en la sección de contenido estático (<staticContent>
) de un archivo web.config
personalizado. En el ejemplo siguiente se supone que la extensión de archivo se cambia de .dll
a .bin
:
<staticContent>
...
<mimeMap fileExtension=".bin" mimeType="application/octet-stream" />
...
</staticContent>
Incluya una actualización para los archivos comprimidos si se usa compresión:
<mimeMap fileExtension=".bin.br" mimeType="application/octet-stream" />
<mimeMap fileExtension=".bin.gz" mimeType="application/octet-stream" />
Quite la entrada de la extensión de archivo .dll
:
- <mimeMap fileExtension=".dll" mimeType="application/octet-stream" />
Quite las entradas de los archivos .dll
comprimidos si se usa compresión:
- <mimeMap fileExtension=".dll.br" mimeType="application/octet-stream" />
- <mimeMap fileExtension=".dll.gz" mimeType="application/octet-stream" />
Para más información sobre los archivos personalizados web.config
, consulte la sección Uso de web.config
personalizado.
Daños en la implementación anterior
Normalmente, en la implementación:
- Solo se reemplazan los archivos que han cambiado, lo que normalmente da lugar a una implementación más rápida.
- Los archivos existentes que no forman parte de la nueva implementación no se modifican para que los use la nueva implementación.
En raras ocasiones, los archivos persistentes de una implementación anterior pueden dañar una nueva implementación. La eliminación completa de la implementación existente (o la aplicación publicada localmente antes de la implementación) puede resolver el problema con una implementación dañada. A menudo, la eliminación de la implementación existente una vez es suficiente para resolver el problema, incluidos los DevOps compilación e implementación de la canalización.
Si determina que siempre es necesario borrar una implementación anterior cuando se está utilizando una canalización de compilación e implementación de DevOps, puede agregar temporalmente un paso a la canalización de compilación para eliminar la implementación anterior de cada nueva implementación hasta que solucione la causa exacta de los daños.
Resolución de errores de comprobación de integridad
Cuando Blazor WebAssembly descarga los archivos de inicio de una aplicación, le indica al navegador que realice comprobaciones de integridad en las respuestas. Blazor envía valores hash SHA-256 para DLL (.dll
), WebAssembly (.wasm
) y otros archivos del archivo blazor.boot.json
, que no se almacenan en caché en los clientes. Los códigos hash de los archivos almacenados en caché se comparan con los del archivo blazor.boot.json
. Para los archivos almacenados en caché con un hash correspondiente, Blazor usa los archivos almacenados en caché. De lo contrario, los archivos se solicitan desde el servidor. Después de descargar un archivo, su hash se comprueba de nuevo para la validación de integridad. El explorador genera un error si se produce un error en la comprobación de integridad de cualquier archivo descargado.
Algoritmo de Blazor para administrar la integridad de los archivos:
- Garantiza que la aplicación no corre el riesgo de cargar un conjunto de archivos incoherentes, por ejemplo, si se aplica una nueva implementación al servidor web mientras el usuario se encuentra en el proceso de descarga de los archivos de aplicación. Los archivos incoherentes pueden dar lugar a un funcionamiento incorrecto de la aplicación.
- Garantiza que el explorador del usuario nunca almacene en caché respuestas incoherentes o no válidas, lo que puede impedir que se inicie la aplicación aunque el usuario actualice manualmente la página.
- Hace que sea seguro almacenar en caché las respuestas y no comprobar los cambios en el lado servidor hasta que cambien los códigos hash SHA-256 esperados, por lo que las cargas de páginas posteriores implican menos solicitudes y se completan mucho más rápido.
Si el servidor web devuelve respuestas que no coinciden con los códigos hash SHA-256 esperados, verá un error similar al del ejemplo siguiente en la consola para desarrolladores del explorador:
No se ha podido encontrar ninguna síntesis válida en el atributo "integrity" del recurso "https://myapp.example.com/_framework/MyBlazorApp.dll" con la integridad de SHA-256 calculada "IIa70iwvmEg5WiDV17OpQ5eCztNYqL186J56852RpJY=". El recurso se ha bloqueado.
En la mayoría de los casos, la advertencia no indica un problema con la comprobación de integridad. En su lugar, la advertencia normalmente significa que existe otro problema.
Para obtener el origen de referencia de arranque de Blazor WebAssembly, vea el archivo Boot.WebAssembly.ts
en el repositorio dotnet/aspnetcore
de GitHub.
Nota
Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, usa la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, vea Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Diagnóstico de problemas de integridad
Cuando se compila una aplicación, el manifiesto de blazor.boot.json
generado describe los códigos hash SHA-256 de los recursos de arranque en el momento en que se ha generado la salida de la compilación. La comprobación de integridad se supera siempre que los algoritmos hash SHA-256 de blazor.boot.json
coincidan con los archivos entregados al explorador.
Los motivos comunes por los que se produce un error incluyen:
- La respuesta del servidor web es un error (por ejemplo, 404 No encontrado o 500 Error interno del servidor) en lugar del archivo solicitado por el explorador. El explorador lo detecta como un error de comprobación de integridad y no como un error de respuesta.
- Algo ha cambiado el contenido de los archivos entre la compilación y la entrega de los archivos al explorador. Esto puede ocurrir:
- Si el usuario o las herramientas de compilación modifican manualmente la salida de compilación.
- Si algún aspecto del proceso de implementación ha modificado los archivos. Por ejemplo, si usa un mecanismo de implementación basado en Git, tenga en cuenta que Git convierte de forma transparente los finales de línea de estilo Windows en finales de línea de estilo Unix si confirma archivos en Windows y los comprueba en Linux. El cambio de los finales de línea de archivo cambia los algoritmos hash SHA-256. Para evitar este problema, considere la posibilidad de usar
.gitattributes
para tratar los artefactos de compilación como archivosbinary
. - El servidor web modifica el contenido del archivo como parte del servicio. Por ejemplo, algunas redes de distribución de contenido (CDN) intentan automáticamente minimizar HTML, con lo que se modifica. Es posible que tenga que deshabilitar estas características.
- El archivo
blazor.boot.json
no se carga correctamente o se almacena en caché incorrectamente en el cliente. Entre las causas comunes se incluye una de las siguientes:- Código de desarrollador personalizado mal configurado o que no funciona correctamente.
- Una o varias capas de almacenamiento en caché intermedias mal configuradas.
Para diagnosticar cuál de ellas se aplica en su caso:
- Lea el mensaje de error para darse cuenta de qué archivo está desencadenando el error.
- Abra las herramientas de desarrollo del explorador y mire en la pestaña Red. Si es necesario, vuelva a cargar la página para ver la lista de solicitudes y respuestas. Busque el archivo que desencadena el error en esa lista.
- Compruebe el código de estado HTTP en la respuesta. Si el servidor devuelve un valor distinto de 200 - Correcto (u otro código de estado 2XX), tiene un problema de servidor por diagnosticar. Por ejemplo, el código de estado 403 significa que hay un problema de autorización, mientras que el código de estado 500 significa que el servidor está dando error de una manera no especificada. Consulte los registros del servidor para diagnosticar y corregir la aplicación.
- Si el código de estado es 200 - Correcto para el recurso, examine el contenido de la respuesta en las herramientas de desarrollo del explorador y compruebe que el contenido coincida con los datos esperados. Por ejemplo, un problema común es configurar erróneamente el enrutamiento de modo que las solicitudes devuelvan los datos de
index.html
incluso para otros archivos. Asegúrese de que las respuestas a las solicitudes de.wasm
son archivos binarios de WebAssembly y que las respuestas a las solicitudes de.dll
son archivos binarios de ensamblado de .NET. Si no es así, tiene un problema de enrutamiento del lado servidor por diagnosticar. - Trate de validar la salida publicada e implementada de la aplicación con el script de PowerShell para solucionar problemas de integridad.
Si confirma que el servidor está devolviendo datos plausiblemente correctos, debe haber algo más que modifique el contenido entre la compilación y la entrega del archivo. Para investigarlo:
- Examine la cadena de herramientas de compilación y el mecanismo de implementación en caso de que estén modificando archivos después de compilarlos. Un ejemplo de esto es cuando GIT transforma los finales de línea de los archivos, tal y como se ha descrito anteriormente.
- Examine el servidor web o la configuración de CDN en caso de que estén configurados para modificar las respuestas de forma dinámica (por ejemplo, intentando minimizar HTML). Está adecuado que el servidor web implemente la compresión HTTP (por ejemplo, devolviendo
content-encoding: br
ocontent-encoding: gzip
), ya que esto no afecta al resultado después de la descompresión. Sin embargo, no es adecuado que el servidor web modifique los datos sin comprimir.
Script de PowerShell para solucionar problemas de integridad
Use el script integrity.ps1
de PowerShell para validar una aplicación Blazor publicada e implementada. El script se proporciona para PowerShell Core 7 o posterior como punto inicial cuando la aplicación tiene problemas de integridad que el marco Blazor no puede identificar. La personalización del script puede ser necesaria para las aplicaciones, incluso si se ejecuta en una versión de PowerShell posterior a la versión 7.2.0.
El script revisa los archivos de la carpeta publish
y los descarga de la aplicación implementada para detectar problemas en los distintos manifiestos que contienen valores hash de integridad. Estas comprobaciones deben detectar los problemas más comunes:
- Modificó un archivo en la salida publicada sin darse cuenta.
- La aplicación no se implementó correctamente en el destino de la implementación o hubo algún cambio en el entorno del destino de la implementación.
- Hay diferencias entre la aplicación implementada y la salida de la publicación de la aplicación.
Use el comando siguiente en un shell de comandos de PowerShell para invocar el script:
.\integrity.ps1 {BASE URL} {PUBLISH OUTPUT FOLDER}
En el ejemplo siguiente, el script se ejecuta en una aplicación que se ejecuta localmente en https://localhost:5001/
:
.\integrity.ps1 https://localhost:5001/ C:\TestApps\BlazorSample\bin\Release\net6.0\publish\
Marcadores de posición:
{BASE URL}
: la dirección URL de la aplicación implementada. Se requiere la barra diagonal (/
).{PUBLISH OUTPUT FOLDER}
: la ruta de acceso a la carpetapublish
de la aplicación o a la ubicación donde se publica la aplicación para la implementación.
Nota
Al clonar el repositorio de GitHub dotnet/AspNetCore.Docs
, Bitdefender o cualquier otro antivirus del sistema podrían poner en cuarentena el script integrity.ps1
. Normalmente, la tecnología de detección heurística de un antivirus intercepta el archivo, buscando simplemente patrones en archivos que podrían indicar la presencia de malware. Para evitar que el antivirus ponga el archivo en cuarentena, agregue una excepción al antivirus antes de clonar el repositorio. El ejemplo siguiente es una ruta de acceso típica al script en un sistema Windows. Ajuste la ruta de acceso según sea necesario para otros sistemas. El marcador de posición {USER}
es el segmento de la ruta de acceso del usuario.
C:\Users\{USER}\Documents\GitHub\AspNetCore.Docs\aspnetcore\blazor\host-and-deploy\webassembly\_samples\integrity.ps1
Advertencia: La creación de excepciones para el antivirus es peligrosa y solo se debe realizar cuando tenga la certeza de que el archivo es seguro.
Comparar la suma de comprobación de un archivo con un valor de suma de comprobación válido no garantiza la seguridad de los archivos, pero modificar un archivo de forma que mantenga un valor de suma de comprobación no es trivial para los usuarios malintencionados. Por lo tanto, las sumas de comprobación son útiles como enfoque de seguridad general. Compare la suma de comprobación del archivo local integrity.ps1
con uno de los valores siguientes:
- SHA256:
32c24cb667d79a701135cb72f6bae490d81703323f61b8af2c7e5e5dc0f0c2bb
- MD5:
9cee7d7ec86ee809a329b5406fbf21a8
Obtenga la suma de comprobación del archivo en el sistema operativo Windows con el siguiente comando. Proporcione la ruta de acceso y el nombre de archivo para el marcador de posición {PATH AND FILE NAME}
e indique el tipo de suma de comprobación que se debe generar para el marcador de posición {SHA512|MD5}
, bien SHA256
o MD5
:
CertUtil -hashfile {PATH AND FILE NAME} {SHA256|MD5}
Si tiene algún motivo para preocuparse de que la validación de la suma de comprobación no sea lo suficientemente segura en su entorno, consúltelo con el responsable de seguridad de su organización para obtener instrucciones.
Para obtener más información, consulte Información general sobre la protección contra amenazas del antivirus Microsoft Defender.
Deshabilitación de la comprobación de integridad para aplicaciones que no son de PWA
En la mayoría de los casos, no deshabilite la comprobación de integridad. Al deshabilitar la comprobación de integridad, no se soluciona el problema subyacente que ha causado las respuestas inesperadas y se pierden las ventajas mencionadas anteriormente.
Puede haber casos en los que no se pueda confiar en el servidor web para que devuelva respuestas coherentes, y solo le queda la opción de deshabilitar temporalmente las comprobaciones de integridad hasta que se resuelva el problema subyacente.
Para deshabilitar las comprobaciones de integridad, agregue lo siguiente a un grupo de propiedades en el archivo del proyecto de la aplicación Blazor WebAssembly (.csproj
):
<BlazorCacheBootResources>false</BlazorCacheBootResources>
BlazorCacheBootResources
también deshabilita el comportamiento predeterminado de Blazorde almacenar en caché .dll
, .wasm
y otros archivos según sus algoritmos hash SHA-256, ya que la propiedad indica que no se puede confiar en la exactitud de los algoritmos hash SHA-256. Incluso con esta configuración, es posible que la memoria caché HTTP normal del explorador siga almacenando en caché esos archivos, pero que esto suceda o no depende de la configuración del servidor web y de los encabezados de cache-control
a los que sirve.
Nota
La propiedad BlazorCacheBootResources
no deshabilita las comprobaciones de integridad de las aplicaciones web progresivas (PWA). Para obtener instrucciones relativas a las PWA, consulte la sección Deshabilitación de la comprobación de integridad para aplicaciones PWA.
No se puede proporcionar una lista exhaustiva de escenarios en los que es necesario deshabilitar la comprobación de integridad. Los servidores pueden responder a una solicitud de maneras arbitrarias fuera del ámbito del marco Blazor. El marco proporciona el valor BlazorCacheBootResources
para que la aplicación se pueda ejecutar a costa de perder una garantía de integridad que la aplicación puede proporcionar. Una vez más, no se recomienda deshabilitar la comprobación de integridad, especialmente para las implementaciones de producción. Los desarrolladores deben intentar resolver el problema de integridad subyacente que provoca un error en la comprobación de la integridad.
Algunos casos generales que pueden causar problemas de integridad son los siguientes:
- Se ejecuta en HTTP, donde no se puede comprobar la integridad.
- Si el proceso de implementación modifica los archivos después de la publicación de alguna manera.
- Si el host modifica los archivos de alguna manera.
Deshabilitación de la comprobación de integridad para aplicaciones PWA
La plantilla de aplicación web progresiva (PWA) de Blazor contiene un archivo service-worker.published.js
sugerido que es responsable de capturar y almacenar archivos de la aplicación para su uso sin conexión. Se trata de un proceso independiente del mecanismo de inicio de la aplicación normal y tiene su propia lógica de comprobación de integridad independiente.
Dentro del archivo service-worker.published.js
, está presente la línea siguiente:
.map(asset => new Request(asset.url, { integrity: asset.hash }));
Para deshabilitar la comprobación de la integridad, quite el parámetro integrity
cambiando la línea por lo siguiente:
.map(asset => new Request(asset.url));
De nuevo, deshabilitar la comprobación de la integridad significa que se pierden las garantías de seguridad que ofrece este servicio. Por ejemplo, existe el riesgo de que si el explorador del usuario almacena en caché la aplicación en el momento exacto en que implementa una nueva versión, podría almacenar en caché algunos archivos de la implementación anterior y otros de la implementación nueva. Si eso sucede, la aplicación se bloquea en un estado interrumpido hasta que implemente una actualización adicional.