Hospedaje e implementación de ASP.NET Core Blazor WebAssembly

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.

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.

Compilación ahead-of-time (AOT)

Blazor WebAssembly admite la compilación ahead-of-time (AOT), donde puede compilar el código de .NET directamente en WebAssembly. La compilación AOT da como resultado mejoras de rendimiento en tiempo de ejecución a costa de un tamaño de aplicación mayor.

Sin habilitar la compilación AOT, las aplicaciones Blazor WebAssembly se ejecutan en el explorador mediante un intérprete de lenguaje intermedio (IL) de .NET implementado en WebAssembly. Dado que se interpreta el código de .NET, las aplicaciones normalmente se ejecutan más lentamente de lo que lo harían en un entorno de ejecución just-in-time (JIT) de .NET del lado servidor. La compilación AOT soluciona este problema de rendimiento mediante la compilación del código .NET de una aplicación directamente en WebAssembly para la ejecución nativa de WebAssembly con el explorador. La mejora del rendimiento de AOT puede producir mejoras drásticas para las aplicaciones que ejecutan tareas que consumen mucha CPU. El inconveniente de usar la compilación AOT es que las aplicaciones compiladas con AOT suelen ser mayores que sus equivalentes interpretadas con IL, por lo que normalmente tardan más tiempo en descargarse en el cliente cuando se solicitan por primera vez.

Para habilitar la compilación AOT de WebAssembly, agregue la propiedad <RunAOTCompilation> establecida en true al archivo de proyecto de la aplicación Blazor WebAssembly:

<PropertyGroup>
  <RunAOTCompilation>true</RunAOTCompilation>
</PropertyGroup>

Para compilar la aplicación en WebAssembly, publique la aplicación. La publicación de la configuración Release garantiza que la vinculación del lenguaje intermedio (IL) de .NET también se ejecuta para reducir el tamaño de la aplicación publicada:

dotnet publish -c Release

La compilación AOT de WebAssembly solo se realiza cuando se publica el proyecto. La compilación AOT no se usa cuando el proyecto se ejecuta durante el desarrollo (entorno Development) porque la compilación AOT normalmente tarda varios minutos en proyectos pequeños y, potencialmente, mucho más tiempo en proyectos más grandes. La reducción del tiempo de compilación para la compilación AOT está en desarrollo para futuras versiones de ASP.NET Core.

El tamaño de una aplicación Blazor WebAssembly compilada con AOT suele ser mayor que si la aplicación se compilara en IL de .NET. Aunque la diferencia de tamaño depende de la aplicación, la mayoría de las aplicaciones compiladas con AOT son aproximadamente el doble del tamaño que sus versiones compiladas con IL. Esto significa que el uso de la compilación AOT da como resultado mejoras de rendimiento en tiempo de ejecución a costa del rendimiento del tiempo de carga. Dependerá de la aplicación si merece la pena usar la compilación AOT a pesar de esta contrapartida. Las aplicaciones Blazor WebAssembly que consumen mucha CPU suelen beneficiarse al máximo de la compilación AOT.

Revinculación en tiempo de ejecución

Una de las partes más grandes de una aplicación Blazor WebAssembly es el entorno de ejecución de .NET basado en WebAssembly (dotnet.wasm) que el explorador debe descargar cuando el explorador de un usuario accede por primera vez a la aplicación. Al volver a vincular el entorno de ejecución de WebAssembly de .NET, se recorta el código en tiempo de ejecución sin usar y, por tanto, se mejora la velocidad de descarga.

La revinculación en tiempo de ejecución se realiza automáticamente al publicar una aplicación. La reducción del tamaño es especialmente considerable al deshabilitar la globalización. Para más información, consulte Globalización y localización de Blazor de ASP.NET Core.

Compatibilidad con dependencias nativas

Las aplicaciones Blazor WebAssembly pueden usar dependencias nativas compiladas para ejecutarse en WebAssembly. Puede vincular estáticamente dependencias nativas en el entorno de ejecución de WebAssembly de .NET mediante las herramientas de compilación de WebAssembly de .NET, las mismas herramientas que se usan para compilar con antelación una aplicación de Blazor para WebAssembly o para volver a vincular el entorno de ejecución para quitar las características no utilizadas.

Las herramientas de compilación de WebAssembly de .NET se basan en Emscripten, una cadena de herramientas del compilador para la plataforma web. Para instalar las herramientas de compilación de WebAssembly de .NET, use cualquiera de los enfoques siguientes:

  • Seleccione el componente opcional en el instalador de Visual Studio.
  • Ejecute dotnet workload install wasm-tools desde un símbolo del sistema administrativo.

Agregue dependencias nativas a una aplicación de Blazor WebAssembly mediante la adición de elementos NativeFileReference en el archivo del proyecto de la aplicación. Cuando se compila el proyecto, las herramientas de compilación de WebAssembly de .NET pasan cada NativeFileReference a Emscripten para que se compilen y vinculen al entorno de ejecución. A continuación, inserte p/invoke en el código nativo del código .NET de la aplicación.

Por lo general, cualquier código nativo portable se puede usar como dependencia nativa con Blazor WebAssembly. Puede agregar dependencias nativas al código C/C++ o al código compilado previamente mediante Emscripten:

  • Archivos objeto (.o)
  • Archivos de almacenamiento (.a)
  • Bitcode (.bc)
  • Módulos de WebAssembly independientes (.wasm)

Normalmente, las dependencias precompiladas deben compilarse con la misma versión de Emscripten que se usa para compilar el entorno de ejecución de WebAssembly de .NET.

Uso de código nativo

Agregue una función de C nativa simple a una aplicación Blazor WebAssembly:

  1. Cree un proyecto de Blazor WebAssembly .

  2. Agregue un archivo Test.c al proyecto.

  3. Agregue una función de C en Test.c para calcular factoriales:

    int fact(int n)
    {
        if (n == 0) return 1;
        return n * fact(n - 1);
    }
    
  4. Agregue NativeFileReference para Test.c en el archivo del proyecto de la aplicación:

    <ItemGroup>
      <NativeFileReference Include="Test.c" />
    </ItemGroup>
    
  5. En un componente de Razor (.razor), agregue DllImportAttribute para la función fact en la biblioteca Test generada y llame al método fact a partir del código de .NET en el componente:

    @using System.Runtime.InteropServices
    
    <p>@fact(3)</p>
    
    @code {
        [DllImport("Test")]
        static extern int fact(int n);
    }
    

Al compilar la aplicación con las herramientas de compilación de WebAssembly de .NET instaladas, el código C nativo se compila y vincula al entorno de ejecución de WebAssembly de .NET (dotnet.wasm). La compilación y vinculación pueden tardar unos minutos. Una vez compilada la aplicación, ejecútela para ver el valor factorial representado.

Nota

Durante el período de la versión preliminar 6.0, es posible que reciba un error de compilación en compilaciones posteriores que dice que otro proceso está utilizando el ensamblado de salida. Se trata de un problema conocido que se solucionará para la versión general de .NET 6. Para solucionar el problema de forma alternativa, vuelva a generar el proyecto una segunda vez.

Uso de bibliotecas

Los paquetes NuGet pueden contener dependencias nativas para su uso en WebAssembly. Estas bibliotecas y su funcionalidad nativa están disponibles para cualquier aplicación Blazor WebAssembly. Los archivos de las dependencias nativas deben compilarse para WebAssembly y empaquetarse en la browser-wasm carpeta específica de la arquitectura. No se hace referencia automáticamente a las dependencias específicas de WebAssembly y se debe hacer referencia a ellas manualmente como NativeFileReference. Los autores de paquetes pueden optar por agregar las referencias nativas incluyendo un archivo .props en el paquete con las referencias.

SkiaSharp es una biblioteca de gráficos 2D multiplataforma para .NET basada en la biblioteca de gráficos Skia nativa y ahora tiene compatibilidad en versión preliminar con Blazor WebAssembly.

Advertencia

Microsoft no es propietario de SkiaSharp ni de la biblioteca de gráficos Skia y tampoco se encarga de su mantenimiento. Microsoft no admite el ejemplo de demostración de esta sección y no debe usarse en producción.

Para usar SkiaSharp en una aplicación Blazor WebAssembly:

  1. Agregue una referencia de paquete al paquete SkiaSharp.Views.Blazor en un proyecto Blazor WebAssembly. Use el proceso de Visual Studio para agregar paquetes a una aplicación (Administrar paquetes NuGet) o ejecute el comando dotnet add package en un shell de comandos:

    dotnet add package –-prerelease SkiaSharp.Views.Blazor
    

    Nota

    En el momento de redactar el artículo, el paquete SkiaSharp.Views.Blazor es un paquete NuGet en versión preliminar no diseñado para usarse en producción.

  2. Agregue un componente SKCanvasView a la aplicación con lo siguiente:

    • Espacios de nombres SkiaSharp y SkiaSharp.Views.Blazor.
    • Lógica que se trazará en el componente de vista de lienzo de SkiaSharp (SKCanvasView).

    Pages/NativeDependencyExample.razor:

    @page "/native-dependency-example"
    @using SkiaSharp
    @using SkiaSharp.Views.Blazor
    
    <PageTitle>Native dependency</PageTitle>
    
    <h1>Native dependency example with SkiaSharp</h1>
    
    <SKCanvasView OnPaintSurface="OnPaintSurface" />
    
    @code {
        private void OnPaintSurface(SKPaintSurfaceEventArgs e)
        {
            var canvas = e.Surface.Canvas;
            canvas.Clear(SKColors.White);
            using var paint = new SKPaint
            {
                Color = SKColors.Black,
                IsAntialias = true,
                TextSize = 24
            };
            canvas.DrawText("SkiaSharp", 0, 24, paint);
        }
    }
    
  3. Compile la aplicación; esta operación puede tardar varios minutos. Ejecute la aplicación y vaya al componente NativeDependencyExample en /native-dependency-example.

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 en 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. Cuando se usa un proyecto hospedado 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 (como es el caso de las páginas de GitHub), 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:

      <script type="module">
        import { BrotliDecode } from './decode.min.js';
        Blazor.start({
          loadBootResource: function (type, name, defaultUri, integrity) {
            if (type !== 'dotnetjs' && location.hostname !== 'localhost') {
              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 más información sobre la carga de los recursos de arranque, vea Inicio de Blazor en ASP.NET Core.

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 hospedada. 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 componente About (href="About").
  • About.razor: componente About.

Cuando se solicita el documento predeterminado de la aplicación mediante la barra de direcciones del explorador (por ejemplo, https://www.contoso.com/):

  1. El explorador realiza una solicitud.
  2. Se devuelve la página predeterminada, que suele ser index.html.
  3. index.html arranca la aplicación.
  4. Se carga el enrutador de Blazor y se representa el componente Main de Razor.

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 más información, vea los siguientes artículos:

Implementación hospedada con varias aplicaciones Blazor WebAssembly

Configuración de la aplicación

Las soluciones de Blazor hospedadas pueden servir para varias aplicaciones Blazor WebAssembly.

Nota

En el ejemplo de esta sección se hace referencia al uso de una solución de Visual Studio, pero el uso de Visual Studio y de una solución de Visual Studio no es necesario para que varias aplicaciones cliente funcionen en un escenario de aplicaciones Blazor WebAssembly hospedadas. Si no usa Visual Studio, omita el archivo {SOLUTION NAME}.sln y los demás archivos creados para Visual Studio.

En el ejemplo siguiente:

  • La aplicación cliente inicial (primera) es el proyecto de cliente predeterminado de una solución creada a partir de la plantilla de proyecto Blazor WebAssembly. Se puede acceder a la primera aplicación cliente en un explorador desde la dirección URL /FirstApp en el puerto 5001 o con un host de firstapp.com.
  • Se agrega una segunda aplicación cliente a la solución, SecondBlazorApp.Client. Se puede acceder a la segunda aplicación cliente en un explorador desde la dirección URL /SecondApp en el puerto 5002 o con un host de secondapp.com.

Use una solución de Blazor hospedada existente o cree una solución a partir de la plantilla de proyecto hospedada de Blazor:

  • En el archivo de proyecto de la aplicación cliente, agregue una propiedad <StaticWebAssetBasePath> a <PropertyGroup> con un valor de FirstApp para establecer la ruta de acceso base para los recursos estáticos del proyecto:

    <PropertyGroup>
      ...
      <StaticWebAssetBasePath>FirstApp</StaticWebAssetBasePath>
    </PropertyGroup>
    
  • Agregue una segunda aplicación cliente a la solución:

    • Agregue una carpeta denominada SecondClient a la carpeta de la solución. La carpeta de la solución creada a partir de la plantilla de proyecto contiene las carpetas y el archivo de la solución siguientes una vez agregada la carpeta SecondClient:

      • Client (carpeta)
      • SecondClient (carpeta)
      • Server (carpeta)
      • Shared (carpeta)
      • {SOLUTION NAME}.sln (archivo)

      El marcador de posición {SOLUTION NAME} es el nombre de la solución.

    • Cree una aplicación Blazor WebAssembly denominada SecondBlazorApp.Client en la carpeta SecondClient de la plantilla de proyecto de Blazor WebAssembly.

    • En el archivo de proyecto de la aplicación SecondBlazorApp.Client:

      • Agregue una propiedad <StaticWebAssetBasePath> a <PropertyGroup> con un valor de SecondApp:

        <PropertyGroup>
          ...
          <StaticWebAssetBasePath>SecondApp</StaticWebAssetBasePath>
        </PropertyGroup>
        
      • Agregue una referencia de proyecto al proyecto Shared:

        <ItemGroup>
          <ProjectReference Include="..\Shared\{SOLUTION NAME}.Shared.csproj" />
        </ItemGroup>
        

        El marcador de posición {SOLUTION NAME} es el nombre de la solución.

  • En el archivo del proyecto de la aplicación de servidor, cree una referencia de proyecto para la aplicación cliente SecondBlazorApp.Client agregada:

    <ItemGroup>
      <ProjectReference Include="..\Client\{SOLUTION NAME}.Client.csproj" />
      <ProjectReference Include="..\SecondClient\SecondBlazorApp.Client.csproj" />
      <ProjectReference Include="..\Shared\{SOLUTION NAME}.Shared.csproj" />
    </ItemGroup>
    

    El marcador de posición {SOLUTION NAME} es el nombre de la solución.

  • En el archivo Properties/launchSettings.json de la aplicación de servidor, configure el elemento applicationUrl del perfil de Kestrel ({SOLUTION NAME}.Server) para acceder a las aplicaciones cliente en los puertos 5001 y 5002:

    "applicationUrl": "https://localhost:5001;https://localhost:5002",
    
  • En el archivo Program.cs de la aplicación de servidor, quite las líneas siguientes, que aparecen después de la llamada a UseHttpsRedirection:

    app.UseBlazorFrameworkFiles();
    app.UseStaticFiles();
    
    app.UseRouting();
    
    app.MapRazorPages();
    app.MapControllers();
    app.MapFallbackToFile("index.html");
    

    Agregue middleware que asigna solicitudes a las aplicaciones cliente. En el ejemplo siguiente se configura el middleware para que se ejecute cuando:

    • El puerto de solicitud es 5001 para la aplicación cliente original o 5002 para la aplicación cliente agregada.

    • El host de solicitud es firstapp.com para la aplicación cliente original o secondapp.com para la aplicación cliente agregada.

      Nota

      El ejemplo que se muestra en esta sección requiere una configuración adicional para:

      • Acceder a las aplicaciones en los dominios de host de ejemplo, firstapp.com y secondapp.com.
      • Certificados que permitan a las aplicaciones cliente habilitar la seguridad TLS (HTTPS).

      La configuración necesaria queda fuera del ámbito de este artículo y depende de cómo se hospede la solución. Para más información, vea los artículos sobre hospedaje e implementación.

    Coloque el código siguiente donde se quitaron las líneas anteriormente:

    app.MapWhen(ctx => ctx.Request.Host.Port == 5001 || 
        ctx.Request.Host.Equals("firstapp.com"), first =>
    {
        first.Use((ctx, nxt) =>
        {
            ctx.Request.Path = "/FirstApp" + ctx.Request.Path;
            return nxt();
        });
    
        first.UseBlazorFrameworkFiles("/FirstApp");
        first.UseStaticFiles();
        first.UseStaticFiles("/FirstApp");
        first.UseRouting();
    
        first.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapFallbackToFile("/FirstApp/{*path:nonfile}", 
                "FirstApp/index.html");
        });
    });
    
    app.MapWhen(ctx => ctx.Request.Host.Port == 5002 || 
        ctx.Request.Host.Equals("secondapp.com"), second =>
    {
        second.Use((ctx, nxt) =>
        {
            ctx.Request.Path = "/SecondApp" + ctx.Request.Path;
            return nxt();
        });
    
        second.UseBlazorFrameworkFiles("/SecondApp");
        second.UseStaticFiles();
        second.UseStaticFiles("/SecondApp");
        second.UseRouting();
    
        second.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapFallbackToFile("/SecondApp/{*path:nonfile}", 
                "SecondApp/index.html");
        });
    });
    
  • En el controlador de pronóstico meteorológico (Controllers/WeatherForecastController.cs) de la aplicación de servidor, reemplace la ruta existente ([Route("[controller]")]) a WeatherForecastController por las rutas siguientes:

    [Route("FirstApp/[controller]")]
    [Route("SecondApp/[controller]")]
    

    El middleware agregado a la canalización de procesamiento de solicitudes de la aplicación de servidor anteriormente modifica las solicitudes entrantes a /WeatherForecast por /FirstApp/WeatherForecast o /SecondApp/WeatherForecast en función del puerto (5001/5002) o el dominio (firstapp.com/secondapp.com). Las rutas de controlador anteriores son necesarias para devolver datos meteorológicos de la aplicación de servidor a las aplicaciones cliente.

Recursos estáticos y bibliotecas de clases para varias aplicaciones Blazor WebAssembly

Use los métodos siguientes para los recursos estáticos de referencia:

  • Cuando el recurso se encuentra en la carpeta wwwroot de la aplicación cliente, proporcione la ruta de acceso de la forma habitual:

    <img alt="..." src="/{PATH AND FILE NAME}" />
    

    El marcador de posición {PATH AND FILE NAME} es la ruta de acceso y el nombre de archivo en wwwroot.

  • Cuando el recurso se encuentra en la carpeta wwwroot de una biblioteca de clases de Razor (RCL), haga referencia al recurso estático de la aplicación cliente según las instrucciones del Interfaz de usuario reutilizable de Razor en bibliotecas de clases con ASP.NET Core:

    <img alt="..." src="_content/{PACKAGE ID}/{PATH AND FILE NAME}" />
    

    El marcador de posición {PACKAGE ID} es el id. de paquete de la biblioteca. El id. de paquete tiene como valor predeterminado el nombre de ensamblado del proyecto si <PackageId> no se especifica en el archivo del proyecto. El marcador de posición {PATH AND FILE NAME} es la ruta de acceso y el nombre de archivo en wwwroot.

Para obtener más información sobre RCL, vea:

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.

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. En este momento no hay disponible una imagen de servidor de Linux para hospedar la aplicación. Se está trabajando para habilitar este escenario.

Aplicación web estática de Azure

Para obtener más información, consulte 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, consulte Compilación de un sitio web estático en IIS.

Los recursos publicados se crean en la carpeta /bin/Release/{TARGET FRAMEWORK}/publish. Hospede 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:

  • Se establecen los tipos MIME de las siguientes extensiones de archivo:
    • .dll: application/octet-stream
    • .json: application/json
    • .wasm: application/wasm
    • .woff: application/font-woff
    • .woff2: application/font-woff
  • Se habilita la compresión HTTP de los siguientes tipos MIME:
    • application/octet-stream
    • application/wasm
  • Se establecen reglas del módulo URL Rewrite:
    • Proporcione el subdirectorio donde residen los recursos estáticos de la aplicación (wwwroot/{PATH REQUESTED}).
    • Cree 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).

Uso de un archivo web.config personalizado

Para usar un archivo web.config personalizado, coloque el archivo web.config personalizado en la raíz de la carpeta del proyecto. Configure el proyecto para publicar recursos específicos de IIS mediante PublishIISAssets en el archivo de proyecto de la aplicación y publique el proyecto:

<PropertyGroup>
  <PublishIISAssets>true</PublishIISAssets>
</PropertyGroup>

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. Use el instalador de plataforma web para instalar el módulo:

  1. De forma local, vaya a la página de descargas del módulo URL Rewrite. 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.
  2. 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> al 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> con inheritInChildApplications establecido en false:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <location path="." inheritInChildApplications="false">
        <system.webServer>
          <handlers>
            <add name="aspNetCore" ... />
          </handlers>
          <aspNetCore ... />
        </system.webServer>
      </location>
    </configuration>
    

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.

Compresión Brotli y Gzip

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.
  • 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 de web.config de ejemplo.

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 cómo solucionar problemas de las implementaciones en IIS, vea Solución de problemas de ASP.NET Core en Azure App Service e IIS.

Almacenamiento de Azure

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 blob index.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:

    1. Haga clic con el botón derecho en el archivo y seleccione Propiedades.
    2. 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 Blazor WebAssembly en CentOS 7 o posterior:

  1. 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>
    
  2. Coloque el archivo de configuración de Apache en el directorio /etc/httpd/conf.d/, que es el directorio de configuración de Apache predeterminado en CentOS 7.

  3. Coloque los archivos de la aplicación en el directorio /var/www/blazorapp (la ubicación especificada para DocumentRoot en el archivo de configuración).

  4. Reinicie el servicio de Apache.

Para más información, vea mod_mime y mod_deflate.

GitHub Pages

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, vea 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.

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 run --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 con dotnet 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 run --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 con dotnet 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 run --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 con dotnet 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
    

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 obtener más información, vea Configuración del recortador de ASP.NET Core Blazor.

Cambio de la extensión de nombre de archivo de los archivos DLL

En caso de que necesite cambiar las extensiones de nombre de los archivos .dll publicados de la aplicación, siga las instrucciones de esta sección.

Después de publicar la aplicación, use 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. Establezca como destino los archivos .dll que están en el directorio wwwroot de la salida publicada de la aplicación (por ejemplo, {CONTENT ROOT}/bin/Release/netstandard2.1/publish/wwwroot).

En los ejemplos siguientes se cambia el nombre de los archivos .dll para que usen la extensión de archivo .bin.

En Windows:

dir .\_framework\_bin | rename-item -NewName { $_.name -replace ".dll\b",".bin" }
((Get-Content .\_framework\blazor.boot.json -Raw) -replace '.dll"','.bin"') | Set-Content .\_framework\blazor.boot.json

Si los recursos de trabajo de servicio también están en uso, agregue el siguiente comando:

((Get-Content .\service-worker-assets.js -Raw) -replace '.dll"','.bin"') | Set-Content .\service-worker-assets.js

En Linux o macOS:

for f in _framework/_bin/*; do mv "$f" "`echo $f | sed -e 's/\.dll/.bin/g'`"; done
sed -i 's/\.dll"/.bin"/g' _framework/blazor.boot.json

Si los recursos de trabajo de servicio también están en uso, agregue el siguiente comando:

sed -i 's/\.dll"/.bin"/g' service-worker-assets.js

Para usar una extensión de archivo diferente a .bin, reemplace .bin en los comandos anteriores.

Para dirigirse a los archivos comprimidos blazor.boot.json.gz y blazor.boot.json.br, adopte uno de los métodos siguientes:

  • Quite los archivos comprimidos blazor.boot.json.gz y blazor.boot.json.br. Con este enfoque, la compresión está deshabilitada.
  • Vuelva a comprimir el archivo blazor.boot.json actualizado.

Las instrucciones anteriores también se aplican cuando se usan recursos de trabajo de servicio. Quite o vuelva a comprimir wwwroot/service-worker-assets.js.br y wwwroot/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 se usa un script de PowerShell colocado en la raíz del proyecto.

ChangeDLLExtensions.ps1::

param([string]$filepath,[string]$tfm)
dir $filepath\bin\Release\$tfm\wwwroot\_framework\_bin | rename-item -NewName { $_.name -replace ".dll\b",".bin" }
((Get-Content $filepath\bin\Release\$tfm\wwwroot\_framework\blazor.boot.json -Raw) -replace '.dll"','.bin"') | Set-Content $filepath\bin\Release\$tfm\wwwroot\_framework\blazor.boot.json
Remove-Item $filepath\bin\Release\$tfm\wwwroot\_framework\blazor.boot.json.gz

Si los recursos de trabajo de servicio también están en uso, agregue el siguiente comando:

((Get-Content $filepath\bin\Release\$tfm\wwwroot\service-worker-assets.js -Raw) -replace '.dll"','.bin"') | Set-Content $filepath\bin\Release\$tfm\wwwroot\service-worker-assets.js

En el archivo del proyecto, el script se ejecuta después de publicar la aplicación:

<Target Name="ChangeDLLFileExtensions" AfterTargets="Publish" Condition="'$(Configuration)'=='Release'">
  <Exec Command="powershell.exe -command &quot;&amp; { .\ChangeDLLExtensions.ps1 '$(SolutionDir)' '$(TargetFramework)'}&quot;" />
</Target>

Nota

Al cambiar el nombre y la carga diferida de los mismos ensamblados, vea la guía de Ensamblados de carga diferida en Blazor WebAssembly de ASP.NET Core.

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. Usa la información del archivo blazor.boot.json para especificar los valores hash de SHA-256 esperados para .dll, .wasm y otros archivos. Esto es beneficioso por los siguientes motivos:

  • Garantiza que no se 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 provocar un comportamiento indefinido.
  • Garantiza que el explorador del usuario nunca almacene en caché las respuestas incoherentes o no válidas, lo que podría impedir que se inicie la aplicación aunque actualice manualmente la página.
  • Hace que sea seguro almacenar en caché las respuestas y ni siquiera comprobar los cambios en el servidor hasta que cambien los algoritmos 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 algoritmos hash SHA-256 esperados, verá un error similar al siguiente en la consola del desarrollador del explorador:

No se pudo encontrar ninguna síntesis válida en el atributo "Integrity" del recurso "https://myapp.example.com/_framework/MyBlazor App.dll" con la integridad de SHA-256 calculada "IIa70iwvmEg5WiDV17OpQ5eCztNYqL186J56852RpJY=". El recurso se ha bloqueado.

En la mayoría de los casos, esto no supone un problema con la propia comprobación de la integridad. Significa en realidad que hay algún otro problema del cual le está advirtiendo la comprobación de la integridad.

Diagnóstico de problemas de integridad

Cuando se compila una aplicación, el manifiesto de blazor.boot.json generado describe los algoritmos hash SHA-256 de los recursos de arranque (por ejemplo, .dll, .wasm y otros archivos) en el momento en que se genera el resultado 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 son:

  • 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 archivos binary.
    • 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.

Para diagnosticar cuál de ellas se aplica en su caso:

  1. Lea el mensaje de error para darse cuenta de qué archivo está desencadenando el error.
  2. 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.
  3. 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.
  4. 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.
  5. 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 o content-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 6 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 6.2.7.

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}

Marcadores de posición:

  • {BASE URL}: la dirección URL de la aplicación implementada.
  • {PUBLISH OUTPUT FOLDER}: la ruta de acceso a la carpeta publish 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: 6b0dc7aba5d8489136bb2969036432597615b11b4e432535e173ca077a0449c4
  • MD5: f0c800a4c72604bd47f3c19f5f0bb4f4

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 más información, vea Descripción de malware & otras amenazas.

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 las comprobaciones de integridad. Para deshabilitar las comprobaciones de integridad, agregue lo siguiente a un grupo de propiedades en el archivo de .csproj del proyecto de Blazor WebAssembly:

<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.

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.

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.

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.

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 en 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. Cuando se usa un proyecto hospedado 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 (como es el caso de las páginas de GitHub), 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:

      <script type="module">
        import { BrotliDecode } from './decode.min.js';
        Blazor.start({
          loadBootResource: function (type, name, defaultUri, integrity) {
            if (type !== 'dotnetjs' && location.hostname !== 'localhost') {
              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 más información sobre la carga de los recursos de arranque, vea Inicio de Blazor en ASP.NET Core.

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 hospedada. 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 componente About (href="About").
  • About.razor: componente About.

Cuando se solicita el documento predeterminado de la aplicación mediante la barra de direcciones del explorador (por ejemplo, https://www.contoso.com/):

  1. El explorador realiza una solicitud.
  2. Se devuelve la página predeterminada, que suele ser index.html.
  3. index.html arranca la aplicación.
  4. Se carga el enrutador de Blazor y se representa el componente Main de Razor.

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 más información, vea los siguientes artículos:

Implementación hospedada con varias aplicaciones Blazor WebAssembly

Configuración de la aplicación

Las soluciones de Blazor hospedadas pueden servir para varias aplicaciones Blazor WebAssembly.

Nota

En el ejemplo de esta sección se hace referencia al uso de una solución de Visual Studio, pero el uso de Visual Studio y de una solución de Visual Studio no es necesario para que varias aplicaciones cliente funcionen en un escenario de aplicaciones Blazor WebAssembly hospedadas. Si no usa Visual Studio, omita el archivo {SOLUTION NAME}.sln y los demás archivos creados para Visual Studio.

En el ejemplo siguiente:

  • La aplicación cliente inicial (primera) es el proyecto de cliente predeterminado de una solución creada a partir de la plantilla de proyecto Blazor WebAssembly. Se puede acceder a la primera aplicación cliente en un explorador desde la dirección URL /FirstApp en el puerto 5001 o con un host de firstapp.com.
  • Se agrega una segunda aplicación cliente a la solución, SecondBlazorApp.Client. Se puede acceder a la segunda aplicación cliente en un explorador desde la dirección URL /SecondApp en el puerto 5002 o con un host de secondapp.com.

Use una solución de Blazor hospedada existente o cree una solución a partir de la plantilla de proyecto hospedada de Blazor:

  • En el archivo de proyecto de la aplicación cliente, agregue una propiedad <StaticWebAssetBasePath> a <PropertyGroup> con un valor de FirstApp para establecer la ruta de acceso base para los recursos estáticos del proyecto:

    <PropertyGroup>
      ...
      <StaticWebAssetBasePath>FirstApp</StaticWebAssetBasePath>
    </PropertyGroup>
    
  • Agregue una segunda aplicación cliente a la solución:

    • Agregue una carpeta denominada SecondClient a la carpeta de la solución. La carpeta de la solución creada a partir de la plantilla de proyecto contiene las carpetas y el archivo de la solución siguientes una vez agregada la carpeta SecondClient:

      • Client (carpeta)
      • SecondClient (carpeta)
      • Server (carpeta)
      • Shared (carpeta)
      • {SOLUTION NAME}.sln (archivo)

      El marcador de posición {SOLUTION NAME} es el nombre de la solución.

    • Cree una aplicación Blazor WebAssembly denominada SecondBlazorApp.Client en la carpeta SecondClient de la plantilla de proyecto de Blazor WebAssembly.

    • En el archivo de proyecto de la aplicación SecondBlazorApp.Client:

      • Agregue una propiedad <StaticWebAssetBasePath> a <PropertyGroup> con un valor de SecondApp:

        <PropertyGroup>
          ...
          <StaticWebAssetBasePath>SecondApp</StaticWebAssetBasePath>
        </PropertyGroup>
        
      • Agregue una referencia de proyecto al proyecto Shared:

        <ItemGroup>
          <ProjectReference Include="..\Shared\{SOLUTION NAME}.Shared.csproj" />
        </ItemGroup>
        

        El marcador de posición {SOLUTION NAME} es el nombre de la solución.

  • En el archivo del proyecto de la aplicación de servidor, cree una referencia de proyecto para la aplicación cliente SecondBlazorApp.Client agregada:

    <ItemGroup>
      <ProjectReference Include="..\Client\{SOLUTION NAME}.Client.csproj" />
      <ProjectReference Include="..\SecondClient\SecondBlazorApp.Client.csproj" />
      <ProjectReference Include="..\Shared\{SOLUTION NAME}.Shared.csproj" />
    </ItemGroup>
    

    El marcador de posición {SOLUTION NAME} es el nombre de la solución.

  • En el archivo Properties/launchSettings.json de la aplicación de servidor, configure el elemento applicationUrl del perfil de Kestrel ({SOLUTION NAME}.Server) para acceder a las aplicaciones cliente en los puertos 5001 y 5002:

    "applicationUrl": "https://localhost:5001;https://localhost:5002",
    
  • En el método Startup.Configure de la aplicación de servidor (Startup.cs), quite las líneas siguientes, que aparecen después de la llamada a UseHttpsRedirection:

    app.UseBlazorFrameworkFiles();
    app.UseStaticFiles();
    
    app.UseRouting();
    
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapControllers();
        endpoints.MapFallbackToFile("index.html");
    });
    

    Agregue middleware que asigna solicitudes a las aplicaciones cliente. En el ejemplo siguiente se configura el middleware para que se ejecute cuando:

    • El puerto de solicitud es 5001 para la aplicación cliente original o 5002 para la aplicación cliente agregada.

    • El host de solicitud es firstapp.com para la aplicación cliente original o secondapp.com para la aplicación cliente agregada.

      Nota

      El ejemplo que se muestra en esta sección requiere una configuración adicional para:

      • Acceder a las aplicaciones en los dominios de host de ejemplo, firstapp.com y secondapp.com.
      • Certificados que permitan a las aplicaciones cliente habilitar la seguridad TLS (HTTPS).

      La configuración necesaria queda fuera del ámbito de este artículo y depende de cómo se hospede la solución. Para más información, vea los artículos sobre hospedaje e implementación.

    Coloque el código siguiente donde se quitaron las líneas anteriormente:

    app.MapWhen(ctx => ctx.Request.Host.Port == 5001 || 
        ctx.Request.Host.Equals("firstapp.com"), first =>
    {
        first.Use((ctx, nxt) =>
        {
            ctx.Request.Path = "/FirstApp" + ctx.Request.Path;
            return nxt();
        });
    
        first.UseBlazorFrameworkFiles("/FirstApp");
        first.UseStaticFiles();
        first.UseStaticFiles("/FirstApp");
        first.UseRouting();
    
        first.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapFallbackToFile("/FirstApp/{*path:nonfile}", 
                "FirstApp/index.html");
        });
    });
    
    app.MapWhen(ctx => ctx.Request.Host.Port == 5002 || 
        ctx.Request.Host.Equals("secondapp.com"), second =>
    {
        second.Use((ctx, nxt) =>
        {
            ctx.Request.Path = "/SecondApp" + ctx.Request.Path;
            return nxt();
        });
    
        second.UseBlazorFrameworkFiles("/SecondApp");
        second.UseStaticFiles();
        second.UseStaticFiles("/SecondApp");
        second.UseRouting();
    
        second.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapFallbackToFile("/SecondApp/{*path:nonfile}", 
                "SecondApp/index.html");
        });
    });
    
  • En el controlador de pronóstico meteorológico (Controllers/WeatherForecastController.cs) de la aplicación de servidor, reemplace la ruta existente ([Route("[controller]")]) a WeatherForecastController por las rutas siguientes:

    [Route("FirstApp/[controller]")]
    [Route("SecondApp/[controller]")]
    

    El middleware agregado al método Startup.Configure de la aplicación de servidor anteriormente modifica las solicitudes entrantes a /WeatherForecast por /FirstApp/WeatherForecast o /SecondApp/WeatherForecast en función del puerto (5001/5002) o el dominio (firstapp.com/secondapp.com). Las rutas de controlador anteriores son necesarias para devolver datos meteorológicos de la aplicación de servidor a las aplicaciones cliente.

Recursos estáticos y bibliotecas de clases para varias aplicaciones Blazor WebAssembly

Use los métodos siguientes para los recursos estáticos de referencia:

  • Cuando el recurso se encuentra en la carpeta wwwroot de la aplicación cliente, proporcione la ruta de acceso de la forma habitual:

    <img alt="..." src="/{PATH AND FILE NAME}" />
    

    El marcador de posición {PATH AND FILE NAME} es la ruta de acceso y el nombre de archivo en wwwroot.

  • Cuando el recurso se encuentra en la carpeta wwwroot de una biblioteca de clases de Razor (RCL), haga referencia al recurso estático de la aplicación cliente según las instrucciones del Interfaz de usuario reutilizable de Razor en bibliotecas de clases con ASP.NET Core:

    <img alt="..." src="_content/{PACKAGE ID}/{PATH AND FILE NAME}" />
    

    El marcador de posición {PACKAGE ID} es el id. de paquete de la biblioteca. El id. de paquete tiene como valor predeterminado el nombre de ensamblado del proyecto si <PackageId> no se especifica en el archivo del proyecto. El marcador de posición {PATH AND FILE NAME} es la ruta de acceso y el nombre de archivo en wwwroot.

Para obtener más información sobre RCL, vea:

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.

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. En este momento no hay disponible una imagen de servidor de Linux para hospedar la aplicación. Se está trabajando para habilitar este escenario.

Aplicación web estática de Azure

Para obtener más información, consulte 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, consulte Compilación de un sitio web estático en IIS.

Los recursos publicados se crean en la carpeta /bin/Release/{TARGET FRAMEWORK}/publish. Hospede 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:

  • Se establecen los tipos MIME de las siguientes extensiones de archivo:
    • .dll: application/octet-stream
    • .json: application/json
    • .wasm: application/wasm
    • .woff: application/font-woff
    • .woff2: application/font-woff
  • Se habilita la compresión HTTP de los siguientes tipos MIME:
    • application/octet-stream
    • application/wasm
  • Se establecen reglas del módulo URL Rewrite:
    • Proporcione el subdirectorio donde residen los recursos estáticos de la aplicación (wwwroot/{PATH REQUESTED}).
    • Cree 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).

Uso de un archivo web.config personalizado

Para usar un archivo web.config personalizado, coloque el archivo web.config personalizado en la raíz de la carpeta del proyecto. Configure el proyecto para publicar recursos específicos de IIS mediante PublishIISAssets en el archivo de proyecto de la aplicación y publique el proyecto:

<PropertyGroup>
  <PublishIISAssets>true</PublishIISAssets>
</PropertyGroup>

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. Use el instalador de plataforma web para instalar el módulo:

  1. De forma local, vaya a la página de descargas del módulo URL Rewrite. 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.
  2. 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> al 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> con inheritInChildApplications establecido en false:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <location path="." inheritInChildApplications="false">
        <system.webServer>
          <handlers>
            <add name="aspNetCore" ... />
          </handlers>
          <aspNetCore ... />
        </system.webServer>
      </location>
    </configuration>
    

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.

Compresión Brotli y Gzip

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.
  • 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 de web.config de ejemplo.

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 cómo solucionar problemas de las implementaciones en IIS, vea Solución de problemas de ASP.NET Core en Azure App Service e IIS.

Almacenamiento de Azure

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 blob index.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:

    1. Haga clic con el botón derecho en el archivo y seleccione Propiedades.
    2. 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 Blazor WebAssembly en CentOS 7 o posterior:

  1. 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>
    
  2. Coloque el archivo de configuración de Apache en el directorio /etc/httpd/conf.d/, que es el directorio de configuración de Apache predeterminado en CentOS 7.

  3. Coloque los archivos de la aplicación en el directorio /var/www/blazorapp (la ubicación especificada para DocumentRoot en el archivo de configuración).

  4. Reinicie el servicio de Apache.

Para más información, vea mod_mime y mod_deflate.

GitHub Pages

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, vea 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.

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 run --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 con dotnet 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 run --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 con dotnet 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 run --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 con dotnet 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
    

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 obtener más información, vea Configuración del recortador de ASP.NET Core Blazor.

Cambio de la extensión de nombre de archivo de los archivos DLL

En caso de que necesite cambiar las extensiones de nombre de los archivos .dll publicados de la aplicación, siga las instrucciones de esta sección.

Después de publicar la aplicación, use 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. Establezca como destino los archivos .dll que están en el directorio wwwroot de la salida publicada de la aplicación (por ejemplo, {CONTENT ROOT}/bin/Release/netstandard2.1/publish/wwwroot).

En los ejemplos siguientes se cambia el nombre de los archivos .dll para que usen la extensión de archivo .bin.

En Windows:

dir .\_framework\_bin | rename-item -NewName { $_.name -replace ".dll\b",".bin" }
((Get-Content .\_framework\blazor.boot.json -Raw) -replace '.dll"','.bin"') | Set-Content .\_framework\blazor.boot.json

Si los recursos de trabajo de servicio también están en uso, agregue el siguiente comando:

((Get-Content .\service-worker-assets.js -Raw) -replace '.dll"','.bin"') | Set-Content .\service-worker-assets.js

En Linux o macOS:

for f in _framework/_bin/*; do mv "$f" "`echo $f | sed -e 's/\.dll/.bin/g'`"; done
sed -i 's/\.dll"/.bin"/g' _framework/blazor.boot.json

Si los recursos de trabajo de servicio también están en uso, agregue el siguiente comando:

sed -i 's/\.dll"/.bin"/g' service-worker-assets.js

Para usar una extensión de archivo diferente a .bin, reemplace .bin en los comandos anteriores.

Para dirigirse a los archivos comprimidos blazor.boot.json.gz y blazor.boot.json.br, adopte uno de los métodos siguientes:

  • Quite los archivos comprimidos blazor.boot.json.gz y blazor.boot.json.br. Con este enfoque, la compresión está deshabilitada.
  • Vuelva a comprimir el archivo blazor.boot.json actualizado.

Las instrucciones anteriores también se aplican cuando se usan recursos de trabajo de servicio. Quite o vuelva a comprimir wwwroot/service-worker-assets.js.br y wwwroot/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 se usa un script de PowerShell colocado en la raíz del proyecto.

ChangeDLLExtensions.ps1::

param([string]$filepath,[string]$tfm)
dir $filepath\bin\Release\$tfm\wwwroot\_framework\_bin | rename-item -NewName { $_.name -replace ".dll\b",".bin" }
((Get-Content $filepath\bin\Release\$tfm\wwwroot\_framework\blazor.boot.json -Raw) -replace '.dll"','.bin"') | Set-Content $filepath\bin\Release\$tfm\wwwroot\_framework\blazor.boot.json
Remove-Item $filepath\bin\Release\$tfm\wwwroot\_framework\blazor.boot.json.gz

Si los recursos de trabajo de servicio también están en uso, agregue el siguiente comando:

((Get-Content $filepath\bin\Release\$tfm\wwwroot\service-worker-assets.js -Raw) -replace '.dll"','.bin"') | Set-Content $filepath\bin\Release\$tfm\wwwroot\service-worker-assets.js

En el archivo del proyecto, el script se ejecuta después de publicar la aplicación:

<Target Name="ChangeDLLFileExtensions" AfterTargets="Publish" Condition="'$(Configuration)'=='Release'">
  <Exec Command="powershell.exe -command &quot;&amp; { .\ChangeDLLExtensions.ps1 '$(SolutionDir)' '$(TargetFramework)'}&quot;" />
</Target>

Nota

Al cambiar el nombre y la carga diferida de los mismos ensamblados, vea la guía de Ensamblados de carga diferida en Blazor WebAssembly de ASP.NET Core.

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. Usa la información del archivo blazor.boot.json para especificar los valores hash de SHA-256 esperados para .dll, .wasm y otros archivos. Esto es beneficioso por los siguientes motivos:

  • Garantiza que no se 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 provocar un comportamiento indefinido.
  • Garantiza que el explorador del usuario nunca almacene en caché las respuestas incoherentes o no válidas, lo que podría impedir que se inicie la aplicación aunque actualice manualmente la página.
  • Hace que sea seguro almacenar en caché las respuestas y ni siquiera comprobar los cambios en el servidor hasta que cambien los algoritmos 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 algoritmos hash SHA-256 esperados, verá un error similar al siguiente en la consola del desarrollador del explorador:

No se pudo encontrar ninguna síntesis válida en el atributo "Integrity" del recurso "https://myapp.example.com/_framework/MyBlazor App.dll" con la integridad de SHA-256 calculada "IIa70iwvmEg5WiDV17OpQ5eCztNYqL186J56852RpJY=". El recurso se ha bloqueado.

En la mayoría de los casos, esto no supone un problema con la propia comprobación de la integridad. Significa en realidad que hay algún otro problema del cual le está advirtiendo la comprobación de la integridad.

Diagnóstico de problemas de integridad

Cuando se compila una aplicación, el manifiesto de blazor.boot.json generado describe los algoritmos hash SHA-256 de los recursos de arranque (por ejemplo, .dll, .wasm y otros archivos) en el momento en que se genera el resultado 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 son:

  • 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 archivos binary.
    • 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.

Para diagnosticar cuál de ellas se aplica en su caso:

  1. Lea el mensaje de error para darse cuenta de qué archivo está desencadenando el error.
  2. 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.
  3. 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.
  4. 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.
  5. 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 o content-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 6 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 6.2.7.

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}

Marcadores de posición:

  • {BASE URL}: la dirección URL de la aplicación implementada.
  • {PUBLISH OUTPUT FOLDER}: la ruta de acceso a la carpeta publish 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: 6b0dc7aba5d8489136bb2969036432597615b11b4e432535e173ca077a0449c4
  • MD5: f0c800a4c72604bd47f3c19f5f0bb4f4

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 más información, vea Descripción de malware & otras amenazas.

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 las comprobaciones de integridad. Para deshabilitar las comprobaciones de integridad, agregue lo siguiente a un grupo de propiedades en el archivo de .csproj del proyecto de Blazor WebAssembly:

<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.

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.

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.

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.

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 en 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. Cuando se usa un proyecto hospedado 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 (como es el caso de las páginas de GitHub), 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:

      <script type="module">
        import { BrotliDecode } from './decode.min.js';
        Blazor.start({
          loadBootResource: function (type, name, defaultUri, integrity) {
            if (type !== 'dotnetjs' && location.hostname !== 'localhost') {
              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 más información sobre la carga de los recursos de arranque, vea Inicio de Blazor en ASP.NET Core.

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 hospedada. 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 componente About (href="About").
  • About.razor: componente About.

Cuando se solicita el documento predeterminado de la aplicación mediante la barra de direcciones del explorador (por ejemplo, https://www.contoso.com/):

  1. El explorador realiza una solicitud.
  2. Se devuelve la página predeterminada, que suele ser index.html.
  3. index.html arranca la aplicación.
  4. Se carga el enrutador de Blazor y se representa el componente Main de Razor.

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 más información, vea los siguientes artículos:

Implementación hospedada con varias aplicaciones Blazor WebAssembly

Configuración de la aplicación

Las soluciones de Blazor hospedadas pueden servir para varias aplicaciones Blazor WebAssembly.

Nota

En el ejemplo de esta sección se hace referencia al uso de una solución de Visual Studio, pero el uso de Visual Studio y de una solución de Visual Studio no es necesario para que varias aplicaciones cliente funcionen en un escenario de aplicaciones Blazor WebAssembly hospedadas. Si no usa Visual Studio, omita el archivo {SOLUTION NAME}.sln y los demás archivos creados para Visual Studio.

En el ejemplo siguiente:

  • La aplicación cliente inicial (primera) es el proyecto de cliente predeterminado de una solución creada a partir de la plantilla de proyecto Blazor WebAssembly. Se puede acceder a la primera aplicación cliente en un explorador desde la dirección URL /FirstApp en el puerto 5001 o con un host de firstapp.com.
  • Se agrega una segunda aplicación cliente a la solución, SecondBlazorApp.Client. Se puede acceder a la segunda aplicación cliente en un explorador desde la dirección URL /SecondApp en el puerto 5002 o con un host de secondapp.com.

Use una solución de Blazor hospedada existente o cree una solución a partir de la plantilla de proyecto hospedada de Blazor:

  • En el archivo de proyecto de la aplicación cliente, agregue una propiedad <StaticWebAssetBasePath> a <PropertyGroup> con un valor de FirstApp para establecer la ruta de acceso base para los recursos estáticos del proyecto:

    <PropertyGroup>
      ...
      <StaticWebAssetBasePath>FirstApp</StaticWebAssetBasePath>
    </PropertyGroup>
    
  • Agregue una segunda aplicación cliente a la solución:

    • Agregue una carpeta denominada SecondClient a la carpeta de la solución. La carpeta de la solución creada a partir de la plantilla de proyecto contiene las carpetas y el archivo de la solución siguientes una vez agregada la carpeta SecondClient:

      • Client (carpeta)
      • SecondClient (carpeta)
      • Server (carpeta)
      • Shared (carpeta)
      • {SOLUTION NAME}.sln (archivo)

      El marcador de posición {SOLUTION NAME} es el nombre de la solución.

    • Cree una aplicación Blazor WebAssembly denominada SecondBlazorApp.Client en la carpeta SecondClient de la plantilla de proyecto de Blazor WebAssembly.

    • En el archivo de proyecto de la aplicación SecondBlazorApp.Client:

      • Agregue una propiedad <StaticWebAssetBasePath> a <PropertyGroup> con un valor de SecondApp:

        <PropertyGroup>
          ...
          <StaticWebAssetBasePath>SecondApp</StaticWebAssetBasePath>
        </PropertyGroup>
        
      • Agregue una referencia de proyecto al proyecto Shared:

        <ItemGroup>
          <ProjectReference Include="..\Shared\{SOLUTION NAME}.Shared.csproj" />
        </ItemGroup>
        

        El marcador de posición {SOLUTION NAME} es el nombre de la solución.

  • En el archivo del proyecto de la aplicación de servidor, cree una referencia de proyecto para la aplicación cliente SecondBlazorApp.Client agregada:

    <ItemGroup>
      <ProjectReference Include="..\Client\{SOLUTION NAME}.Client.csproj" />
      <ProjectReference Include="..\SecondClient\SecondBlazorApp.Client.csproj" />
      <ProjectReference Include="..\Shared\{SOLUTION NAME}.Shared.csproj" />
    </ItemGroup>
    

    El marcador de posición {SOLUTION NAME} es el nombre de la solución.

  • En el archivo Properties/launchSettings.json de la aplicación de servidor, configure el elemento applicationUrl del perfil de Kestrel ({SOLUTION NAME}.Server) para acceder a las aplicaciones cliente en los puertos 5001 y 5002:

    "applicationUrl": "https://localhost:5001;https://localhost:5002",
    
  • En el método Startup.Configure de la aplicación de servidor (Startup.cs), quite las líneas siguientes, que aparecen después de la llamada a UseHttpsRedirection:

    app.UseBlazorFrameworkFiles();
    app.UseStaticFiles();
    
    app.UseRouting();
    
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapControllers();
        endpoints.MapFallbackToFile("index.html");
    });
    

    Agregue middleware que asigna solicitudes a las aplicaciones cliente. En el ejemplo siguiente se configura el middleware para que se ejecute cuando:

    • El puerto de solicitud es 5001 para la aplicación cliente original o 5002 para la aplicación cliente agregada.

    • El host de solicitud es firstapp.com para la aplicación cliente original o secondapp.com para la aplicación cliente agregada.

      Nota

      El ejemplo que se muestra en esta sección requiere una configuración adicional para:

      • Acceder a las aplicaciones en los dominios de host de ejemplo, firstapp.com y secondapp.com.
      • Certificados que permitan a las aplicaciones cliente habilitar la seguridad TLS (HTTPS).

      La configuración necesaria queda fuera del ámbito de este artículo y depende de cómo se hospede la solución. Para más información, vea los artículos sobre hospedaje e implementación.

    Coloque el código siguiente donde se quitaron las líneas anteriormente:

    app.MapWhen(ctx => ctx.Request.Host.Port == 5001 || 
        ctx.Request.Host.Equals("firstapp.com"), first =>
    {
        first.Use((ctx, nxt) =>
        {
            ctx.Request.Path = "/FirstApp" + ctx.Request.Path;
            return nxt();
        });
    
        first.UseBlazorFrameworkFiles("/FirstApp");
        first.UseStaticFiles();
        first.UseStaticFiles("/FirstApp");
        first.UseRouting();
    
        first.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapFallbackToFile("/FirstApp/{*path:nonfile}", 
                "FirstApp/index.html");
        });
    });
    
    app.MapWhen(ctx => ctx.Request.Host.Port == 5002 || 
        ctx.Request.Host.Equals("secondapp.com"), second =>
    {
        second.Use((ctx, nxt) =>
        {
            ctx.Request.Path = "/SecondApp" + ctx.Request.Path;
            return nxt();
        });
    
        second.UseBlazorFrameworkFiles("/SecondApp");
        second.UseStaticFiles();
        second.UseStaticFiles("/SecondApp");
        second.UseRouting();
    
        second.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapFallbackToFile("/SecondApp/{*path:nonfile}", 
                "SecondApp/index.html");
        });
    });
    
  • En el controlador de pronóstico meteorológico (Controllers/WeatherForecastController.cs) de la aplicación de servidor, reemplace la ruta existente ([Route("[controller]")]) a WeatherForecastController por las rutas siguientes:

    [Route("FirstApp/[controller]")]
    [Route("SecondApp/[controller]")]
    

    El middleware agregado al método Startup.Configure de la aplicación de servidor anteriormente modifica las solicitudes entrantes a /WeatherForecast por /FirstApp/WeatherForecast o /SecondApp/WeatherForecast en función del puerto (5001/5002) o el dominio (firstapp.com/secondapp.com). Las rutas de controlador anteriores son necesarias para devolver datos meteorológicos de la aplicación de servidor a las aplicaciones cliente.

Recursos estáticos y bibliotecas de clases para varias aplicaciones Blazor WebAssembly

Use los métodos siguientes para los recursos estáticos de referencia:

  • Cuando el recurso se encuentra en la carpeta wwwroot de la aplicación cliente, proporcione la ruta de acceso de la forma habitual:

    <img alt="..." src="/{PATH AND FILE NAME}" />
    

    El marcador de posición {PATH AND FILE NAME} es la ruta de acceso y el nombre de archivo en wwwroot.

  • Cuando el recurso se encuentra en la carpeta wwwroot de una biblioteca de clases de Razor (RCL), haga referencia al recurso estático de la aplicación cliente según las instrucciones del Interfaz de usuario reutilizable de Razor en bibliotecas de clases con ASP.NET Core:

    <img alt="..." src="_content/{PACKAGE ID}/{PATH AND FILE NAME}" />
    

    El marcador de posición {PACKAGE ID} es el id. de paquete de la biblioteca. El id. de paquete tiene como valor predeterminado el nombre de ensamblado del proyecto si <PackageId> no se especifica en el archivo del proyecto. El marcador de posición {PATH AND FILE NAME} es la ruta de acceso y el nombre de archivo en wwwroot.

Para obtener más información sobre RCL, vea:

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.

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. En este momento no hay disponible una imagen de servidor de Linux para hospedar la aplicación. Se está trabajando para habilitar este escenario.

Aplicación web estática de Azure

Para obtener más información, consulte 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, consulte Compilación de un sitio web estático en IIS.

Los recursos publicados se crean en la carpeta /bin/Release/{TARGET FRAMEWORK}/publish. Hospede 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:

  • Se establecen los tipos MIME de las siguientes extensiones de archivo:
    • .dll: application/octet-stream
    • .json: application/json
    • .wasm: application/wasm
    • .woff: application/font-woff
    • .woff2: application/font-woff
  • Se habilita la compresión HTTP de los siguientes tipos MIME:
    • application/octet-stream
    • application/wasm
  • Se establecen reglas del módulo URL Rewrite:
    • Proporcione el subdirectorio donde residen los recursos estáticos de la aplicación (wwwroot/{PATH REQUESTED}).
    • Cree 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).

Uso de un archivo web.config personalizado

Para usar un archivo web.config personalizado, coloque el archivo web.config personalizado en la raíz de la carpeta del proyecto. Configure el proyecto para publicar recursos específicos de IIS mediante PublishIISAssets en el archivo de proyecto de la aplicación y publique el proyecto:

<PropertyGroup>
  <PublishIISAssets>true</PublishIISAssets>
</PropertyGroup>

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. Use el instalador de plataforma web para instalar el módulo:

  1. De forma local, vaya a la página de descargas del módulo URL Rewrite. 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.
  2. 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> al 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> con inheritInChildApplications establecido en false:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <location path="." inheritInChildApplications="false">
        <system.webServer>
          <handlers>
            <add name="aspNetCore" ... />
          </handlers>
          <aspNetCore ... />
        </system.webServer>
      </location>
    </configuration>
    

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.

Compresión Brotli y Gzip

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.
  • 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 de web.config de ejemplo.

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 cómo solucionar problemas de las implementaciones en IIS, vea Solución de problemas de ASP.NET Core en Azure App Service e IIS.

Almacenamiento de Azure

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 blob index.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:

    1. Haga clic con el botón derecho en el archivo y seleccione Propiedades.
    2. 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 Blazor WebAssembly en CentOS 7 o posterior:

  1. 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>
    
  2. Coloque el archivo de configuración de Apache en el directorio /etc/httpd/conf.d/, que es el directorio de configuración de Apache predeterminado en CentOS 7.

  3. Coloque los archivos de la aplicación en el directorio /var/www/blazorapp (la ubicación especificada para DocumentRoot en el archivo de configuración).

  4. Reinicie el servicio de Apache.

Para más información, vea mod_mime y mod_deflate.

GitHub Pages

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, vea 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.

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 run --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 con dotnet 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 run --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 con dotnet 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 run --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 con dotnet 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
    

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, vea Configuración del enlazador de ASP.NET Core Blazor.

Cambio de la extensión de nombre de archivo de los archivos DLL

En caso de que necesite cambiar las extensiones de nombre de los archivos .dll publicados de la aplicación, siga las instrucciones de esta sección.

Después de publicar la aplicación, use 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. Establezca como destino los archivos .dll que están en el directorio wwwroot de la salida publicada de la aplicación (por ejemplo, {CONTENT ROOT}/bin/Release/netstandard2.1/publish/wwwroot).

En los ejemplos siguientes se cambia el nombre de los archivos .dll para que usen la extensión de archivo .bin.

En Windows:

dir .\_framework\_bin | rename-item -NewName { $_.name -replace ".dll\b",".bin" }
((Get-Content .\_framework\blazor.boot.json -Raw) -replace '.dll"','.bin"') | Set-Content .\_framework\blazor.boot.json

Si los recursos de trabajo de servicio también están en uso, agregue el siguiente comando:

((Get-Content .\service-worker-assets.js -Raw) -replace '.dll"','.bin"') | Set-Content .\service-worker-assets.js

En Linux o macOS:

for f in _framework/_bin/*; do mv "$f" "`echo $f | sed -e 's/\.dll/.bin/g'`"; done
sed -i 's/\.dll"/.bin"/g' _framework/blazor.boot.json

Si los recursos de trabajo de servicio también están en uso, agregue el siguiente comando:

sed -i 's/\.dll"/.bin"/g' service-worker-assets.js

Para usar una extensión de archivo diferente a .bin, reemplace .bin en los comandos anteriores.

Para dirigirse a los archivos comprimidos blazor.boot.json.gz y blazor.boot.json.br, adopte uno de los métodos siguientes:

  • Quite los archivos comprimidos blazor.boot.json.gz y blazor.boot.json.br. Con este enfoque, la compresión está deshabilitada.
  • Vuelva a comprimir el archivo blazor.boot.json actualizado.

Las instrucciones anteriores también se aplican cuando se usan recursos de trabajo de servicio. Quite o vuelva a comprimir wwwroot/service-worker-assets.js.br y wwwroot/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 se usa un script de PowerShell colocado en la raíz del proyecto.

ChangeDLLExtensions.ps1::

param([string]$filepath,[string]$tfm)
dir $filepath\bin\Release\$tfm\wwwroot\_framework\_bin | rename-item -NewName { $_.name -replace ".dll\b",".bin" }
((Get-Content $filepath\bin\Release\$tfm\wwwroot\_framework\blazor.boot.json -Raw) -replace '.dll"','.bin"') | Set-Content $filepath\bin\Release\$tfm\wwwroot\_framework\blazor.boot.json
Remove-Item $filepath\bin\Release\$tfm\wwwroot\_framework\blazor.boot.json.gz

Si los recursos de trabajo de servicio también están en uso, agregue el siguiente comando:

((Get-Content $filepath\bin\Release\$tfm\wwwroot\service-worker-assets.js -Raw) -replace '.dll"','.bin"') | Set-Content $filepath\bin\Release\$tfm\wwwroot\service-worker-assets.js

En el archivo del proyecto, el script se ejecuta después de publicar la aplicación:

<Target Name="ChangeDLLFileExtensions" AfterTargets="Publish" Condition="'$(Configuration)'=='Release'">
  <Exec Command="powershell.exe -command &quot;&amp; { .\ChangeDLLExtensions.ps1 '$(SolutionDir)' '$(TargetFramework)'}&quot;" />
</Target>

Nota

Al cambiar el nombre y la carga diferida de los mismos ensamblados, vea la guía de Ensamblados de carga diferida en Blazor WebAssembly de ASP.NET Core.

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. Usa la información del archivo blazor.boot.json para especificar los valores hash de SHA-256 esperados para .dll, .wasm y otros archivos. Esto es beneficioso por los siguientes motivos:

  • Garantiza que no se 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 provocar un comportamiento indefinido.
  • Garantiza que el explorador del usuario nunca almacene en caché las respuestas incoherentes o no válidas, lo que podría impedir que se inicie la aplicación aunque actualice manualmente la página.
  • Hace que sea seguro almacenar en caché las respuestas y ni siquiera comprobar los cambios en el servidor hasta que cambien los algoritmos 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 algoritmos hash SHA-256 esperados, verá un error similar al siguiente en la consola del desarrollador del explorador:

No se pudo encontrar ninguna síntesis válida en el atributo "Integrity" del recurso "https://myapp.example.com/_framework/MyBlazor App.dll" con la integridad de SHA-256 calculada "IIa70iwvmEg5WiDV17OpQ5eCztNYqL186J56852RpJY=". El recurso se ha bloqueado.

En la mayoría de los casos, esto no supone un problema con la propia comprobación de la integridad. Significa en realidad que hay algún otro problema del cual le está advirtiendo la comprobación de la integridad.

Diagnóstico de problemas de integridad

Cuando se compila una aplicación, el manifiesto de blazor.boot.json generado describe los algoritmos hash SHA-256 de los recursos de arranque (por ejemplo, .dll, .wasm y otros archivos) en el momento en que se genera el resultado 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 son:

  • 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 archivos binary.
    • 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.

Para diagnosticar cuál de ellas se aplica en su caso:

  1. Lea el mensaje de error para darse cuenta de qué archivo está desencadenando el error.
  2. 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.
  3. 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.
  4. 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.
  5. 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 o content-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 6 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 6.2.7.

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}

Marcadores de posición:

  • {BASE URL}: la dirección URL de la aplicación implementada.
  • {PUBLISH OUTPUT FOLDER}: la ruta de acceso a la carpeta publish 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: 6b0dc7aba5d8489136bb2969036432597615b11b4e432535e173ca077a0449c4
  • MD5: f0c800a4c72604bd47f3c19f5f0bb4f4

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 más información, vea Descripción de malware & otras amenazas.

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 las comprobaciones de integridad. Para deshabilitar las comprobaciones de integridad, agregue lo siguiente a un grupo de propiedades en el archivo de .csproj del proyecto de Blazor WebAssembly:

<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.

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.