Hospedar e implantar o ASP.NET Core Blazor WebAssembly

Observação

Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Importante

Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.

Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Este artigo explica como hospedar e implantar o Blazor WebAssembly usando o ASP.NET Core, a CDN (Rede de Distribuição de Conteúdo), servidores de arquivos e páginas do GitHub.

Cuidado

Este artigo faz referência ao CentOS, uma distribuição do Linux que está se aproximando do status de EOL (Fim da Vida Útil). Considere seu uso e planeje adequadamente. Para obter mais informações, veja as Diretrizes sobre fim da vida útil do CentOS.

Com o modelo de hospedagem Blazor WebAssembly:

  • O aplicativo do Blazor, suas dependências e o runtime do .NET são baixados no navegador paralelamente.
  • O aplicativo é executado diretamente no thread da interface do usuário do navegador.

Este artigo refere-se ao cenário de implantação no qual o aplicativo Blazor é colocado em um servidor Web ou serviço de hospedagem estática e o .NET não é utilizado para servir o aplicativo Blazor. Essa estratégia é abordada na seção Implantação autônoma, que inclui informações sobre como hospedar um aplicativo do Blazor WebAssembly como subaplicativo do IIS.

Há suporte para as seguintes estratégias de implantação:

  • O aplicativo do Blazor é atendido por um aplicativo ASP.NET Core. Esta estratégia é abordada na seção Implantação hospedada com o ASP.NET Core.
  • O aplicativo do Blazor é colocado em um serviço ou um servidor Web de hospedagem estático, em que o .NET não é usado para atender ao aplicativo do Blazor. Essa estratégia é abordada na seção Implantação autônoma, que inclui informações sobre como hospedar um aplicativo do Blazor WebAssembly como subaplicativo do IIS.
  • Um aplicativo do ASP.NET Core hospeda vários aplicativos do Blazor WebAssembly. Para obter mais informações, confira Vários aplicativos Blazor WebAssembly do ASP.NET Core hospedados.

Diminuir o tamanho máximo do heap para alguns navegadores de dispositivo móvel

Ao criar um aplicativo Blazor que é executado no cliente (projeto .Client de um aplicativo Web Blazor ou aplicativo Blazor WebAssembly autônomo) e destina-se a navegadores de dispositivo móvel, especialmente o Safari no iOS, a diminuição da memória máxima para o aplicativo com a propriedade MSBuild EmccMaximumHeapSize pode ser necessária. O valor padrão é 2.147.483.648 bytes, o que pode ser muito grande e resultar no travamento do aplicativo se o aplicativo tentar alocar mais memória com o navegador falhando em concedê-la. O exemplo a seguir define o valor como 268.435.456 bytes no arquivo Program:

Ao criar um aplicativo Blazor WebAssembly destinado a navegadores de dispositivo móvel, especialmente o Safari no iOS, a diminuição da memória máxima para o aplicativo com a propriedade MSBuild EmccMaximumHeapSize pode ser necessária. O valor padrão é 2.147.483.648 bytes, o que pode ser muito grande e resultar no travamento do aplicativo se o aplicativo tentar alocar mais memória com o navegador falhando em concedê-la. O exemplo a seguir define o valor como 268.435.456 bytes no arquivo Program:

<EmccMaximumHeapSize>268435456</EmccMaximumHeapSize>

Para mais informações sobre as propriedades e destinos do Mono/WebAssembly MSBuild, confira WasmApp.Common.targets (repositório GitHub dotnet/runtime).

Formato de empacotamento Webcil para assemblies .NET

O Webcil é um formato de empacotamento amigável para assemblies .NET projetado para possibilitar o uso do Blazor WebAssembly em ambientes de rede restritivos. Os arquivos Webcil usam um wrapper WebAssembly padrão, em que os assemblies são implantados como arquivos WebAssembly que usam a extensão de arquivo .wasm padrão.

O Webcil é o formato de empacotamento padrão quando você publica um aplicativo Blazor WebAssembly. Para desabilitar o uso do Webcil, defina a seguinte propriedade MS Build no arquivo de projeto do aplicativo:

<PropertyGroup>
  <WasmEnableWebcil>false</WasmEnableWebcil>
</PropertyGroup>

Personalizar a forma como os recursos de inicialização são carregados

Personalize a forma como os recursos de inicialização são carregados usando a API do loadBootResource. Para obter mais informações, confira Inicialização Blazor do ASP.NET Core.

Compactação

Quando um aplicativo do Blazor WebAssembly é publicado, a saída é compactada estaticamente durante a publicação para reduzir o tamanho do aplicativo e remover a sobrecarga para compactação de runtime. Os seguintes algoritmos de compactação são usados:

Blazor depende do host para atender aos arquivos compactados apropriados. Ao hospedar um aplicativo autônomo do Blazor WebAssembly, um trabalho adicional pode ser necessário para garantir que arquivos compactados estaticamente sejam atendidos:

Blazor depende do host para atender aos arquivos compactados apropriados. Ao usar um projeto Hospedado pelo ASP.NET CoreBlazor WebAssembly, o projeto host pode executar a negociação de conteúdo e atender aos arquivos compactados estaticamente. Ao hospedar um aplicativo autônomo do Blazor WebAssembly, um trabalho adicional pode ser necessário para garantir que arquivos compactados estaticamente sejam atendidos:

  • Para configuração de compactação web.config do IIS, confira a seção IIS: compactação de Brotli e Gzip.
  • Ao fazer a hospedagem em soluções de hospedagem estáticas que não dão suporte à negociação de conteúdo de arquivo compactado estaticamente, considere a configuração do aplicativo para buscar e decodificar arquivos compactados em Brotli:

Obtenha o decodificador JavaScript Brotli no google/brotli repositório GitHub. O arquivo de decodificador minimizado é chamado de decode.min.js e encontrado na pasta js do repositório.

Observação

Se a versão minimizada do script decode.js (decode.min.js) falhar, tente usar a versão não minimizada (decode.js).

Atualize o aplicativo para usar o decodificador.

No arquivo wwwroot/index.html, defina autostart como false na marca Blazor do <script>:

<script src="_framework/blazor.webassembly.js" autostart="false"></script>

Após a marca <script> do Blazor e antes da marca </body> de fechamento, adicione o bloco <script> de código JavaScript a seguir.

Aplicativo Web Blazor:

<script type="module">
  import { BrotliDecode } from './decode.min.js';
  Blazor.start({
    webAssembly: {
      loadBootResource: function (type, name, defaultUri, integrity) {
        if (type !== 'dotnetjs' && location.hostname !== 'localhost' && type !== 'configuration' && type !== 'manifest') {
          return (async function () {
            const response = await fetch(defaultUri + '.br', { cache: 'no-cache' });
            if (!response.ok) {
              throw new Error(response.statusText);
            }
            const originalResponseBuffer = await response.arrayBuffer();
            const originalResponseArray = new Int8Array(originalResponseBuffer);
            const decompressedResponseArray = BrotliDecode(originalResponseArray);
            const contentType = type === 
              'dotnetwasm' ? 'application/wasm' : 'application/octet-stream';
            return new Response(decompressedResponseArray, 
              { headers: { 'content-type': contentType } });
          })();
        }
      }
    }
  });
</script>

Blazor WebAssembly autônomo:

<script type="module">
  import { BrotliDecode } from './decode.min.js';
  Blazor.start({
    loadBootResource: function (type, name, defaultUri, integrity) {
      if (type !== 'dotnetjs' && location.hostname !== 'localhost' && type !== 'configuration') {
        return (async function () {
          const response = await fetch(defaultUri + '.br', { cache: 'no-cache' });
          if (!response.ok) {
            throw new Error(response.statusText);
          }
          const originalResponseBuffer = await response.arrayBuffer();
          const originalResponseArray = new Int8Array(originalResponseBuffer);
          const decompressedResponseArray = BrotliDecode(originalResponseArray);
          const contentType = type === 
            'dotnetwasm' ? 'application/wasm' : 'application/octet-stream';
          return new Response(decompressedResponseArray, 
            { headers: { 'content-type': contentType } });
        })();
      }
    }
  });
</script>

Para obter mais informações sobre como carregar recursos de inicialização, confira Inicialização Blazor do AsP.NET Core.

Para desabilitar a compactação, adicione a propriedade do MSBuild CompressionEnabled ao arquivo de projeto do aplicativo e defina o valor como false:

<PropertyGroup>
  <CompressionEnabled>false</CompressionEnabled>
</PropertyGroup>

A propriedade CompressionEnabled pode ser passada para o comando dotnet publish com a seguinte sintaxe em um shell de comando:

dotnet publish -p:CompressionEnabled=false

Para desabilitar a compactação, adicione a propriedade do MSBuild BlazorEnableCompression ao arquivo de projeto do aplicativo e defina o valor como false:

<PropertyGroup>
  <BlazorEnableCompression>false</BlazorEnableCompression>
</PropertyGroup>

A propriedade BlazorEnableCompression pode ser passada para o comando dotnet publish com a seguinte sintaxe em um shell de comando:

dotnet publish -p:BlazorEnableCompression=false

Reescrever as URLs para obter o roteamento correto

O roteamento de solicitações para componentes de página em um aplicativo Blazor WebAssembly não é tão simples quanto o roteamento de solicitações em um aplicativo Blazor Server. Considere um aplicativo do Blazor WebAssembly com dois componentes:

  • Main.razor: é carregado na raiz do aplicativo e contém um link para o componente About (href="About").
  • About.razor: componente About.

Quando o documento padrão do aplicativo é solicitado usando a barra de endereços do navegador (por exemplo, https://www.contoso.com/):

  1. O navegador faz uma solicitação.
  2. A página padrão é retornada, que geralmente é index.html.
  3. index.html inicia o aplicativo.
  4. O componente Router é carregado e o componente RazorMain é renderizado.

Na página principal, a seleção do link para o componente About funciona no cliente porque o roteador do Blazor impede que o navegador faça uma solicitação na Internet para o www.contoso.com no About e atende ao próprio componente About renderizado. Todas as solicitações de pontos de extremidade internos dentro do aplicativo Blazor WebAssembly funcionam da mesma maneira: as solicitações não disparam solicitações baseadas em navegador para recursos hospedados pelo servidor na Internet. O roteador trata das solicitações internamente.

Se uma solicitação for feita usando a barra de endereços do navegador para www.contoso.com/About, a solicitação falhará. Este recurso não existe no host do aplicativo na Internet; portanto, uma resposta 404 – Não Encontrado é retornada.

Como os navegadores fazem solicitações aos hosts baseados na Internet de páginas do lado do cliente, os servidores Web e os serviços de hospedagem precisam reescrever todas as solicitações de recursos que não estão fisicamente no servidor para a página index.html. Quando index.html for retornado, o roteador Blazor do aplicativo assumirá o controle e responderá com o recurso correto.

Ao implantar em um servidor IIS, você pode usar o Módulo de Regravação de URL com o arquivo web.config publicado do aplicativo. Para obter mais informações, confira a seção IIS.

Implantação hospedada com o ASP.NET Core

Uma implantação hospedada atende ao aplicativo do Blazor WebAssembly para os navegadores de um aplicativo do ASP.NET Core que é executado em um servidor da Web.

O aplicativo Blazor WebAssembly cliente é publicado na pasta /bin/Release/{TARGET FRAMEWORK}/publish/wwwroot do aplicativo de servidor, juntamente com qualquer outro ativo Web estático do aplicativo de servidor. Os dois aplicativos são implantados juntos. É necessário um servidor Web capaz de hospedar um aplicativo do ASP.NET Core. Para uma implantação hospedada, o Visual Studio inclui o modelo de projeto do Blazor WebAssemblyAplicativo (modelo do blazorwasm ao usar o comando dotnet new) com a opção Hosted selecionada (-ho|--hosted ao usar o comando dotnet new).

Para obter mais informações, confira os seguintes artigos:

Implantação hospedada de um arquivo executável dependente de estrutura para uma plataforma específica

Para implantar um aplicativo do Blazor WebAssembly hospedado como um executável dependente de estrutura para uma plataforma específica (não independente), use as diretrizes a seguir com base nas ferramentas em uso.

Visual Studio

Por padrão, uma implantação independente é configurada para um perfil de publicação gerado (.pubxml). Confirme se o perfil de publicação do projeto do Server contém a propriedade do MSBuild <SelfContained> definida como false.

No arquivo de perfil de publicação do .pubxml na Server pasta Properties do projeto:

<SelfContained>false</SelfContained>

Defina o RID (Identificador de Runtime) usando a configuração Runtime de Destino na área Configurações da interface do usuário Publicar, que gera a propriedade do MSBuild <RuntimeIdentifier> no perfil de publicação:

<RuntimeIdentifier>{RID}</RuntimeIdentifier>

Na configuração anterior, o espaço reservado {RID} é o RID (Identificador de Runtime).

Publique o projeto Server na configuração Versão.

Observação

É possível publicar um aplicativo com as configurações de perfil de publicação usando a CLI do .NET passando /p:PublishProfile={PROFILE} para o comando dotnet publish, em que o espaço reservado {PROFILE} é o perfil. Para obter mais informações, confira as seções Perfis de publicação e Exemplo de publicação de pasta no artigo Implantação de aplicativo dos perfis de publicação do Visual Studio (.pubxml) para ASP.NET Core. Se você passar o RID no comando dotnet publish e não no perfil de publicação, use a propriedade do MSBuild (/p:RuntimeIdentifier) com o comando, não com a opção -r|--runtime.

CLI do .NET

Configure uma implantação independente colocando a propriedade do MSBuild <SelfContained> em um <PropertyGroup> no arquivo de projeto do projeto Server definido como false:

<SelfContained>false</SelfContained>

Importante

A propriedade SelfContained deve ser colocada no arquivo de projeto do projeto Server. A propriedade não pode ser definida corretamente com o comando dotnet publish usando a opção --no-self-contained ou a propriedade MSBuild do /p:SelfContained=false.

Defina o RID (Identificador de Runtime) usando uma das seguintes abordagens:

  • Opção 1: defina o RID em um <PropertyGroup> no Server arquivo de projeto do projeto:

    <RuntimeIdentifier>{RID}</RuntimeIdentifier>
    

    Na configuração anterior, o espaço reservado {RID} é o RID (Identificador de Runtime).

    Publique o aplicativo na configuração Versão do projeto Server:

    dotnet publish -c Release
    
  • Opção 2: passe o RID no comando dotnet publish como a propriedade do MSBuild (/p:RuntimeIdentifier), não com a opção -r|--runtime:

    dotnet publish -c Release /p:RuntimeIdentifier={RID}
    

    Na configuração anterior, o espaço reservado {RID} é o RID (Identificador de Runtime).

Para obter mais informações, confira os seguintes artigos:

Implantação hospedada com vários aplicativos do Blazor WebAssembly

Para obter mais informações, confira Vários aplicativos Blazor WebAssembly do ASP.NET Core hospedados.

Implantação autônoma

Uma implantação autônoma atende ao aplicativo do Blazor WebAssembly como um conjunto de arquivos estáticos que são solicitados diretamente pelos clientes. Qualquer servidor de arquivos estático é capaz de atender ao aplicativo do Blazor.

Os ativos de implantação autônomos são publicados na pasta /bin/Release/{TARGET FRAMEWORK}/publish/wwwroot.

Serviço de Aplicativo do Azure

Os aplicativos do Blazor WebAssembly podem ser implantados nos Serviços de Aplicativos do Azure no Windows, que hospeda o aplicativo no IIS.

Atualmente, não há suporte para a implantação de um aplicativo autônomo Blazor WebAssembly no Serviço de Aplicativo do Azure para Linux. Recomendamos hospedar um aplicativo autônomo Blazor WebAssembly usando os Aplicativos Web Estáticos do Azure, que dão suporte a esse cenário.

Aplicativos Web Estáticos do Azure

Implante um aplicativo Blazor WebAssembly nos Aplicativos Web Estáticos do Azure usando uma das seguintes abordagens:

Implantação pelo Visual Studio

Para implantar a partir do Visual Studio, crie um perfil de publicação para os Aplicativos Web Estáticos do Azure:

  1. Salve qualquer trabalho não salvo no projeto, pois uma reinicialização do Visual Studio pode ser necessária durante o processo.

  2. Na interface do usuário Publicar do Visual Studio, selecione Destino> Azure>Destino Específico>Aplicativos Web Estáticos do Azure para criar um perfil de publicação.

  3. Se o componente Ferramentas do Azure WebJobs para Visual Studio não estiver instalado, um prompt aparecerá para instalar o componente ASP.NET e desenvolvimento da Web. Siga os prompts para instalar as ferramentas usando o Instalador do Visual Studio. O Visual Studio fecha e reabre automaticamente durante a instalação das ferramentas. Depois que as ferramentas forem instaladas, comece novamente na primeira etapa para criar o perfil de publicação.

  4. Na configuração de perfil de publicação, forneça o nome da assinatura. Selecione uma instância existente ou selecione Criar uma nova instância. Ao criar uma nova instância na interface do usuário Criar Aplicativo Web Estático do portal do Azure, defina os Detalhes da implantação>Fonte como Outro. Aguarde a conclusão da implantação no portal do Azure antes de prosseguir.

  5. Na configuração de perfil de publicação, selecione a instância dos Aplicativos Web Estáticos do Azure no grupo de recursos da instância. Selecione Concluir para criar o perfil de publicação. Se o Visual Studio solicitar a instalação da CLI dos Aplicativos Web Estáticos (SWA), instale a CLI seguindo os prompts. A CLI dos SWA requer NPM/Node.js (documentação do Visual Studio).

Depois que o perfil de publicação for criado, implante o aplicativo na instância dos Aplicativos Web Estáticos do Azure usando o perfil de publicação selecionando o botão Publicar.

Implantar pelo GitHub

Para implantar a partir de um repositório GitHub, consulte Tutorial: criando um aplicativo Web estático com Blazor nos Aplicativos Web Estáticos do Azure.

IIS

O IIS é um servidor de arquivos estático compatível com aplicativos do Blazor. Para configurar o IIS para hospedar o Blazor, confira Criar um site estático no IIS.

Os ativos publicados são criados na pasta /bin/Release/{TARGET FRAMEWORK}/publish ou bin\Release\{TARGET FRAMEWORK}\browser-wasm\publish, dependendo de qual versão do SDK é usada e onde o espaço reservado {TARGET FRAMEWORK} é a estrutura de destino. Hospede o conteúdo da pasta publish no servidor Web ou no serviço de hospedagem.

web.config

Quando um projeto do Blazor é publicado, um arquivo web.config é criado com a seguinte configuração do IIS:

  • tipos MIME
  • A compactação HTTP está habilitada para os seguintes tipos MIME:
    • application/octet-stream
    • application/wasm
  • As regras do Módulo de Reescrita de URL são estabelecidas:
    • Atender ao subdiretório em que residem os ativos estáticos do aplicativo (wwwroot/{PATH REQUESTED}).
    • Criar o roteamento de fallback do SPA, de modo que as solicitações de ativos que não sejam arquivos sejam redirecionadas ao documento padrão do aplicativo na pasta de ativos estáticos dele (wwwroot/index.html).

Usar um web.config personalizado

Para usar um arquivo web.config personalizado:

  1. Coloque o arquivo web.config personalizado na pasta raiz do projeto.
  2. Publique o projeto. Para obter mais informações, confira Hospedar e implantar Blazor do ASP.NET Core.
  1. Coloque o arquivo web.config personalizado na pasta raiz do projeto. Para uma Blazor WebAssemblysolução hospedada, coloque o arquivo na pasta do projeto Server.
  2. Publique o projeto. Para uma solução Blazor WebAssembly hospedada, publique a solução no projeto Server. Para obter mais informações, confira Hospedar e implantar Blazor do ASP.NET Core.

Se a geração ou transformação web.config do SDK durante a publicação não mover o arquivo para os ativos publicados na pasta publish ou modificar a configuração personalizada no seu arquivo web.config personalizado, use qualquer uma das seguintes abordagens, conforme necessário, para assumir o controle total do processo:

  • Se o SDK não gerar o arquivo, por exemplo, em um aplicativo autônomo Blazor WebAssembly em /bin/Release/{TARGET FRAMEWORK}/publish/wwwroot ou bin\Release\{TARGET FRAMEWORK}\browser-wasm\publish, dependendo de qual versão do SDK é usada e onde o espaço reservado {TARGET FRAMEWORK} é a estrutura de destino, defina a propriedade <PublishIISAssets> como true no arquivo de projeto (.csproj). Normalmente, para aplicativos autônomos do WebAssembly, essa é a única configuração necessária para mover um arquivo web.config personalizado e impedir a transformação do arquivo pelo SDK.

    <PropertyGroup>
      <PublishIISAssets>true</PublishIISAssets>
    </PropertyGroup>
    
  • Desabilite a transformação web.config do SDK no arquivo de projeto (.csproj):

    <PropertyGroup>
      <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
    </PropertyGroup>
    
  • Adicione um destino personalizado ao arquivo de projeto (.csproj) para mover um arquivo web.config personalizado. No exemplo a seguir, o arquivo web.config personalizado é colocado pelo desenvolvedor na raiz do projeto. Se o arquivo web.config residir em outro lugar, especifique o caminho para o arquivo em SourceFiles. O exemplo a seguir especifica a pasta publish com $(PublishDir), mas fornece um caminho para DestinationFolder em um local de saída personalizado.

    <Target Name="CopyWebConfig" AfterTargets="Publish">
      <Copy SourceFiles="web.config" DestinationFolder="$(PublishDir)" />
    </Target>
    

Instalação do Módulo de Regeneração de URL

O Módulo de Reescrita de URL é necessário para reescrever URLs. Por padrão, o módulo não está instalado e não está disponível para instalação como um recurso do serviço de função do servidor Web (IIS). O módulo precisa ser baixado do site do IIS. Use o Web Platform Installer para instalar o módulo:

  1. Localmente, navegue até a página de downloads do Módulo de Reescrita de URL. Para obter a versão em inglês, selecione WebPI para baixar o instalador do WebPI. Para outros idiomas, selecione a arquitetura apropriada para o servidor (x86/x64) para baixar o instalador.
  2. Copie o instalador para o servidor. Execute o instalador. Selecione o botão Instalar e aceite os termos de licença. Uma reinicialização do servidor não será necessária após a conclusão da instalação.

Configuração do site

Defina o Caminho físico do site como a pasta do aplicativo. A pasta contém:

  • O arquivo web.config que o IIS usa para configurar o site, incluindo as regras de redirecionamento e os tipos de conteúdo do arquivo necessários.
  • A pasta de ativos estática do aplicativo.

Hospedar como um subaplicativo do IIS

Se um aplicativo autônomo estiver hospedado como subaplicativo do IIS, execute um dos seguintes procedimentos:

  • Desabilite o manipulador de Módulo do ASP.NET Core herdado.

    Remova o manipulador do arquivo Blazorpublicado do aplicativo do web.config adicionando uma seção <handlers> à seção <system.webServer> do arquivo:

    <handlers>
      <remove name="aspNetCore" />
    </handlers>
    
  • Desabilite a herança da seção <system.webServer> do aplicativo raiz (pai) usando um elemento <location> com inheritInChildApplications definido como 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>
    

    Observação

    Desabilitar a herança da seção <system.webServer> do aplicativo raiz (pai) é a configuração padrão para aplicativos publicados usando o SDK do .NET.

O manipulador é removido ou a herança é desativada além da configuração do caminho base do aplicativo. Defina o caminho base do aplicativo no arquivo index.html para o alias do IIS usado ao configurar o subaplicativo no IIS.

Configure o caminho base do aplicativo seguindo as diretrizes do artigo Hospedar e implantar o ASP.NET Core Blazor.

Compactação de Brotli e Gzip

Esta seção se aplica apenas a aplicativos Blazor WebAssembly autônomos.

Esta seção só se aplica a aplicativos autônomos Blazor WebAssembly. Os aplicativos hospedados do Blazor usam um arquivo web.config do aplicativo do ASP.NET Core padrão, não o arquivo vinculado nesta seção.

O IIS pode ser configurado por meio do web.config para atender a ativos Blazor com compactação de Brotli ou Gzip para aplicativos autônomos Blazor WebAssembly. Para ver um arquivo de configuração de exemplo, confira web.config.

A configuração adicional do arquivo de exemplo web.config pode ser necessária nos seguintes cenários:

  • A especificação do aplicativo chama um dos seguintes:
    • Arquivos compactados de serviço que não são configurados pelo arquivo web.config de exemplo.
    • Arquivos compactados de serviço que são configurados pelo arquivo web.config de exemplo em um formato não compactado.
  • A configuração do IIS do servidor (por exemplo, applicationHost.config) fornece padrões do IIS no nível do servidor. Dependendo da configuração no nível do servidor, o aplicativo pode exigir uma configuração diferente do IIS em relação à que o arquivo web.config de exemplo contém.

Para obter mais informações sobre arquivos web.config personalizados, confira a seção Usar um web.config personalizado.

Solução de problemas

Se um 500 – Erro Interno do Servidor for recebido e o Gerenciador do IIS gerar erros ao tentar acessar a configuração do site, confirme se o Módulo de Regeneração de URL está instalado. Quando o módulo não estiver instalado, o arquivo web.config não poderá ser analisado pelo IIS. Isso impede que o Gerenciador do IIS carregue a configuração do site e que o site atenda aos arquivos estáticos do Blazor.

Para obter mais informações sobre a solução de problemas de implantações no IIS, confira Solucionar problemas do ASP.NET Core no Serviço de Aplicativo Azure e no IIS.

Armazenamento do Azure

A hospedagem de arquivo estático do Armazenamento do Azure permite a hospedagem de aplicativo do Blazor sem servidor. Nomes de domínio personalizados, CDN (Rede de Distribuição de Conteúdo) do Azure e HTTPS são compatíveis.

Quando o serviço de blob está habilitado para hospedagem de site estático em uma conta de armazenamento:

  • Defina o Nome do documento de índice como index.html.
  • Defina o Caminho do documento de erro como index.html. Os componentes do Razor e outros pontos de extremidade que não são arquivos não residem em caminhos físicos no conteúdo estático armazenado pelo serviço de blob. Quando uma solicitação para um desses recursos é recebida, a qual deve passar pelo Blazor, o erro 404 – Não Encontrado gerado pelo serviço de blob encaminha a solicitação para o Caminho do documento de erro. O blob index.html retorna e o roteador do Blazor carrega e processa o caminho.

Se os arquivos não forem carregados no runtime devido a tipos MIME inadequados nos cabeçalhos Content-Type dos arquivos, execute uma das seguintes ações:

  • Configure suas ferramentas para definir os tipos MIME corretos (cabeçalhos Content-Type) quando os arquivos forem implantados.

  • Altere os tipos MIME (cabeçalhos Content-Type) para os arquivos depois que o aplicativo for implantado.

    No Gerenciador de Armazenamento (portal do Azure) de cada arquivo:

    1. Clique com o botão direito do mouse no arquivo e selecione Propriedades.
    2. Defina o ContentType e selecione o botão Salvar.

Para saber mais, confira Hospedagem de site estático no Armazenamento do Azure.

Nginx

O arquivo nginx.conf a seguir é simplificado para mostrar como configurar o Nginx para enviar o arquivo index.html sempre que ele não puder encontrar um arquivo correspondente no disco.

events { }
http {
    server {
        listen 80;

        location / {
            root      /usr/share/nginx/html;
            try_files $uri $uri/ /index.html =404;
        }
    }
}

Ao definir o limite de taxa de intermitência do NGINX com limit_req, os aplicativos do Blazor WebAssembly podem exigir um valor de parâmetro grande do burst para permitir o número relativamente grande de solicitações feitas por um aplicativo. Inicialmente, defina o valor como pelo menos 60:

http {
    server {
        ...

        location / {
            ...

            limit_req zone=one burst=60 nodelay;
        }
    }
}

Aumente o valor se a ferramenta de desenvolvedor do navegador ou uma ferramenta de tráfego de rede indicar que as solicitações estão recebendo um código de status 503 – Serviço indisponível.

Para obter mais informações sobre a configuração do servidor Web Nginx de produção, confira Creating NGINX Plus and NGINX Configuration Files (Criando arquivos de configuração do NGINX Plus e do NGINX).

Apache

Para implantar um aplicativo do Blazor WebAssembly no CentOS 7 ou posterior:

  1. Crie o arquivo de configuração do Apache. O exemplo a seguir é um arquivo de configuração simplificado (blazorapp.config):
<VirtualHost *:80>
    ServerName www.example.com
    ServerAlias *.example.com

    DocumentRoot "/var/www/blazorapp"
    ErrorDocument 404 /index.html

    AddType application/wasm .wasm

    <Directory "/var/www/blazorapp">
        Options -Indexes
        AllowOverride None
    </Directory>

    <IfModule mod_deflate.c>
        AddOutputFilterByType DEFLATE text/css
        AddOutputFilterByType DEFLATE application/javascript
        AddOutputFilterByType DEFLATE text/html
        AddOutputFilterByType DEFLATE application/octet-stream
        AddOutputFilterByType DEFLATE application/wasm
        <IfModule mod_setenvif.c>
      BrowserMatch ^Mozilla/4 gzip-only-text/html
      BrowserMatch ^Mozilla/4.0[678] no-gzip
      BrowserMatch bMSIE !no-gzip !gzip-only-text/html
  </IfModule>
    </IfModule>

    ErrorLog /var/log/httpd/blazorapp-error.log
    CustomLog /var/log/httpd/blazorapp-access.log common
</VirtualHost>
<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>
  1. Coloque o arquivo de configuração do Apache no diretório /etc/httpd/conf.d/, que é o diretório de configuração do Apache padrão no CentOS 7.

  2. Coloque os arquivos do aplicativo no diretório /var/www/blazorapp (o local especificado para o DocumentRoot no arquivo de configuração).

  3. Reinicie o serviço do Apache.

Para obter mais informações, consulte mod_mime e mod_deflate.

Páginas do GitHub

O GitHub Action padrão, que implanta as páginas, ignora a implantação de pastas que começam com sublinhado, por exemplo, a pasta _framework. Para implantar pastas que começam com sublinhado, adicione um arquivo .nojekyll vazio ao Git branch.

O Git trata os arquivos JavaScript (JS), como blazor.webassembly.js, como texto e converte terminações de linha de CRLF (alimentação de linha de retorno de carro) em LF (feed de linha) no pipeline de implantação. Essas alterações nos arquivos JS produzem hashes de arquivo diferentes dos enviados pelo Blazor ao cliente no arquivo blazor.boot.json. As incompatibilidades resultam em falhas na verificação de integridade no cliente. Uma abordagem para resolver esse problema é adicionar um arquivo .gitattributes com a linha *.js binary, antes de adicionar os ativos do aplicativo ao Git branch. A linha *.js binary configura o Git para tratar os arquivos JS como arquivos binários, o que evita o processamento dos arquivos no pipeline de implantação. Os hashes dos arquivos não processados correspondem às entradas no arquivo blazor.boot.json e as verificações de integridade do lado do cliente são aprovadas. Para obter mais informações, consulte ASP.NET Core Blazor WebAssembly Runtime do .NET e o cache do lote de aplicativo.

Para lidar com as reescritas de URL, adicione um arquivo wwwroot/404.html com um script que manipule o redirecionamento de solicitação para a página index.html. Para obter um exemplo, confira o SteveSandersonMS/BlazorOnGitHubPagesrepositório GitHub:

Ao usar um site de projeto, em vez de um site de organização, atualize a marca <base> no wwwroot/index.html. Defina o valor de atributo href com o nome do repositório GitHub com uma barra à direita (por exemplo, /my-repository/). No SteveSandersonMS/BlazorOnGitHubPagesrepositório GitHub, a base href é atualizada na publicação pelo .github/workflows/main.yml arquivo de configuração.

Observação

O SteveSandersonMS/BlazorOnGitHubPagesrepositório GitHub não é de propriedade, mantido ou suportado pela .NET Foundation ou pela Microsoft.

Aplicativo autônomo com o Docker

Um aplicativo autônomo Blazor WebAssembly é publicado como um conjunto de arquivos estáticos para hospedagem por um servidor de arquivos estático.

Para hospedar o aplicativo no Docker:

  • Escolha um contêiner do Docker com suporte ao servidor Web, como o Ngnix ou o Apache.
  • Copie os ativos da pasta publish para uma pasta de local definida no servidor Web para atender aos arquivos estáticos.
  • Aplique a configuração adicional conforme necessário para atender ao aplicativo Blazor WebAssembly.

Para obter diretrizes de configuração, confira os seguintes recursos:

Valores de configuração do host

Os aplicativos do Blazor WebAssembly que aceitam os seguintes valores de configuração do host como argumentos de linha de comando no runtime no ambiente de desenvolvimento.

Raiz do conteúdo

O argumento --contentroot define o caminho absoluto para o diretório que contém os arquivos de conteúdo do aplicativo (raiz de conteúdo). Nos exemplos a seguir, /content-root-path é o caminho raiz do conteúdo do aplicativo.

  • Passe o argumento ao executar o aplicativo localmente em um prompt de comando. No diretório do aplicativo, execute:

    dotnet run --contentroot=/content-root-path
    
  • Adicione uma entrada ao arquivo launchSettings.json do aplicativo no perfil do IIS Express. Esta configuração é usada quando o aplicativo é executado com o Depurador do Visual Studio e em um prompt de comando com dotnet run.

    "commandLineArgs": "--contentroot=/content-root-path"
    
  • No Visual Studio, especifique o argumento em Propriedades>Depurar>Argumentos de aplicativo. A configuração do argumento na página de propriedades do Visual Studio adiciona o argumento ao arquivo launchSettings.json.

    --contentroot=/content-root-path
    

Caminho base

O argumento --pathbase define o caminho base do aplicativo para um aplicativo executado localmente com um caminho de URL relativa não raiz (a marca <base> do href é definida como um caminho diferente de / para preparo e produção). Nos exemplos a seguir, /relative-URL-path é o caminho base do aplicativo. Para obter mais informações, confira Caminho base do aplicativo.

Importante

Ao contrário do caminho fornecido ao href da tag <base>, não inclua uma barra à direita (/) ao passar o valor do argumento --pathbase. Se o caminho base do aplicativo for fornecido na tag <base> como <base href="/CoolApp/"> (inclui uma barra à direita), passe o valor do argumento de linha de comando como --pathbase=/CoolApp (nenhuma barra à direita).

  • Passe o argumento ao executar o aplicativo localmente em um prompt de comando. No diretório do aplicativo, execute:

    dotnet run --pathbase=/relative-URL-path
    
  • Adicione uma entrada ao arquivo launchSettings.json do aplicativo no perfil do IIS Express. Esta configuração é usada ao executar o aplicativo com o Depurador do Visual Studio e em um prompt de comando com dotnet run.

    "commandLineArgs": "--pathbase=/relative-URL-path"
    
  • No Visual Studio, especifique o argumento em Propriedades>Depurar>Argumentos de aplicativo. A configuração do argumento na página de propriedades do Visual Studio adiciona o argumento ao arquivo launchSettings.json.

    --pathbase=/relative-URL-path
    

URLs

O argumento --urls define os endereços IP ou os endereços de host com portas e protocolos para escutar solicitações.

  • Passe o argumento ao executar o aplicativo localmente em um prompt de comando. No diretório do aplicativo, execute:

    dotnet run --urls=http://127.0.0.1:0
    
  • Adicione uma entrada ao arquivo launchSettings.json do aplicativo no perfil do IIS Express. Esta configuração é usada ao executar o aplicativo com o Depurador do Visual Studio e em um prompt de comando com dotnet run.

    "commandLineArgs": "--urls=http://127.0.0.1:0"
    
  • No Visual Studio, especifique o argumento em Propriedades>Depurar>Argumentos de aplicativo. A configuração do argumento na página de propriedades do Visual Studio adiciona o argumento ao arquivo launchSettings.json.

    --urls=http://127.0.0.1:0
    

Implantação hospedada no Linux (Nginx)

Configure o aplicativo com o ForwardedHeadersOptions para encaminhar os cabeçalhos X-Forwarded-For e X-Forwarded-Proto seguindo as diretrizes em Configurar o ASP.NET Core para trabalhar com servidores proxy e balanceadores de carga.

Para obter mais informações sobre como definir o caminho base do aplicativo, incluindo a configuração do caminho do subaplicativo, confira Hospedar e implantar o Blazor do ASP.NET Core.

Siga as diretrizes para um aplicativo SignalR do ASP.NET Core com as seguintes alterações:

  • Remova a configuração para buffer de proxy (proxy_buffering off;), pois a configuração só se aplica a SSE (Eventos Enviados pelo Servidor), que não são relevantes para as interações cliente-servidor do aplicativo do Blazor.

  • Altere o caminho do location de /hubroute (location /hubroute { ... }) para o caminho do subaplicativo /{PATH} (location /{PATH} { ... }), em que o espaço reservado {PATH} é o caminho do subaplicativo.

    O exemplo a seguir configura o servidor para um aplicativo que responde a solicitações no caminho raiz /:

    http {
        server {
            ...
            location / {
                ...
            }
        }
    }
    

    O exemplo a seguir configura o caminho do subaplicativo de /blazor:

    http {
        server {
            ...
            location /blazor {
                ...
            }
        }
    }
    

Para obter mais informações e diretrizes de configuração, confira os seguintes recursos:

Configurar o cortador

O Blazor executa o filtro de IL (Linguagem Intermediária) em cada build de Versão para remover a IL desnecessária dos assemblies de saída. Para obter mais informações, confira Configurar o filtro para Blazor do ASP.NET Core.

Configurar o vinculador

O Blazor executa a vinculação de IL (linguagem intermediária) em cada build de Versão para remover a IL desnecessária dos assemblies de saída. Para obter mais informações, confira Configurar o vinculador para Blazor do ASP.NET Core.

Alterar a extensão de nome de arquivo dos arquivos DLL

Esta seção se aplica ao ASP.NET Core 6 e 7.x. No ASP.NET Core no .NET 8 ou posterior, os assemblies .NET são implantados como arquivos WebAssembly (.wasm) usando o formato de arquivo Webcil. No ASP.NET Core no .NET 8 ou posterior, esta seção só se aplicará se o formato de arquivo Webcil tiver sido desabilitado no arquivo de projeto do aplicativo.

Se um dispositivo de firewall, programa antivírus ou segurança de rede estiver bloqueando a transmissão dos arquivos DLL (biblioteca de vínculo dinâmico) do aplicativo (.dll), você poderá seguir as diretrizes nesta seção para alterar as extensões de nome de arquivo dos arquivos DLL publicados do aplicativo.

Observação

Alterar as extensões de nome de arquivo dos arquivos DLL do aplicativo pode não resolver o problema, pois muitos sistemas de segurança examinam o conteúdo dos arquivos do aplicativo, não apenas verificam as extensões de arquivo.

Para uma abordagem mais robusta em ambientes que bloqueiam o download e a execução de arquivos DLL, use o ASP.NET Core no .NET 8 ou posterior, que, por padrão, empacota os assemblies .NET como arquivos WebAssembly (.wasm) utilizando o formato de arquivo Webcil. Para obter mais informações, consulte a seção formato de empacotamento Webcil para assemblies .NET em uma versão 8.0 ou posterior deste artigo.

Existem abordagens de terceiros para lidar com esse problema. Para obter mais informações, confira os recursos em Blazor do Awesome.

Observação

Alterar as extensões de nome de arquivo dos arquivos DLL do aplicativo pode não resolver o problema, pois muitos sistemas de segurança examinam o conteúdo dos arquivos do aplicativo, não apenas verificam as extensões de arquivo.

Para obter uma abordagem mais robusta em ambientes que bloqueiam o download e a execução de arquivos DLL, siga uma das seguintes abordagens:

  • Use ASP.NET Core no .NET 8 ou posterior, que por padrão empacota assemblies .NET como arquivos WebAssembly (.wasm) usando o formato de arquivo Webcil. Para obter mais informações, consulte a seção formato de empacotamento Webcil para assemblies .NET em uma versão 8.0 ou posterior deste artigo.
  • No ASP.NET Core no .NET 6 ou posterior, use um layout de implantação personalizado.

Existem abordagens de terceiros para lidar com esse problema. Para obter mais informações, confira os recursos em Blazor do Awesome.

Depois de publicar o aplicativo, use um script de shell ou um pipeline de build do DevOps para renomear os arquivos .dll para usar uma extensão de arquivo diferente no diretório da saída publicada do aplicativo.

Nos seguintes exemplos:

  • O PS (PowerShell) é usado para atualizar as extensões de arquivo.
  • Os arquivos .dll são renomeados para usar a extensão de arquivo .bin na linha de comando.
  • Os arquivos listados no arquivo publicado blazor.boot.json com uma extensão de arquivo .dll são atualizados para a extensão de arquivo .bin.
  • Se os ativos de trabalho de serviço também estiverem em uso, um comando do PowerShell atualizará os arquivos .dll listados no arquivo service-worker-assets.js para a extensão de arquivo .bin.

Para usar uma extensão de arquivo diferente de .bin, substitua .bin nos comandos a seguir pela extensão de arquivo desejada.

No Windows:

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

No comando anterior, o espaço reservado {PATH} é o caminho para a pasta _framework publicada (por exemplo, .\bin\Release\net6.0\browser-wasm\publish\wwwroot\_framework na pasta raiz do projeto).

Se os ativos de trabalho de serviço também estiverem em uso:

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

No comando anterior, o espaço reservado {PATH} é o caminho para o arquivo service-worker-assets.js publicado.

No Linux ou macOS:

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

No comando anterior, o espaço reservado {PATH} é o caminho para a pasta _framework publicada (por exemplo, .\bin\Release\net6.0\browser-wasm\publish\wwwroot\_framework na pasta raiz do projeto).

Se os ativos de trabalho de serviço também estiverem em uso:

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

No comando anterior, o espaço reservado {PATH} é o caminho para o arquivo service-worker-assets.js publicado.

Para abordar os arquivos compactados blazor.boot.json.gz e blazor.boot.json.br, adote uma das seguintes abordagens:

  • Remova os arquivos compactados blazor.boot.json.gz e blazor.boot.json.br. A compactação está desabilitada com essa abordagem.
  • Compacte novamente o arquivo blazor.boot.json atualizado.

As diretrizes anteriores para o arquivo blazor.boot.json compactado também se aplicam quando os ativos de trabalho de serviço estão em uso. Remova ou compacte novamente service-worker-assets.js.br e service-worker-assets.js.gz. Caso contrário, as verificações de integridade do arquivo falharão no navegador.

O exemplo do Windows a seguir para .NET 6 usa um script do PowerShell colocado na raiz do projeto. O script a seguir, que desabilita a compactação, é a base para modificações adicionais, se você quiser compactar novamente o arquivo blazor.boot.json.

ChangeDLLExtensions.ps1::

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

Se os ativos de trabalho de serviço também estiverem em uso, adicione os seguintes comandos:

((Get-Content $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\service-worker-assets.js -Raw) -replace '.dll"','.bin"') | Set-Content $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\wwwroot\service-worker-assets.js
Remove-Item $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\wwwroot\service-worker-assets.js.gz
Remove-Item $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\wwwroot\service-worker-assets.js.br

No arquivo de projeto, o script é executado depois de publicar o aplicativo para a configuração Release:

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

Observação

Ao renomear e carregar lentamente os mesmos assemblies, confira as diretrizes em Assemblies de carregamento lento no Blazor WebAssembly do ASP.NET Core.

Normalmente, o servidor do aplicativo requer a configuração de ativo estático para atender aos arquivos com a extensão atualizada. Para um aplicativo hospedado pelo IIS, adicione uma entrada de mapa MIME (<mimeMap>) para a nova extensão de arquivo na seção de conteúdo estático (<staticContent>) em um arquivo web.config personalizado. O exemplo a seguir pressupõe que a extensão de arquivo foi alterada de .dll para .bin:

<staticContent>
  ...
  <mimeMap fileExtension=".bin" mimeType="application/octet-stream" />
  ...
</staticContent>

Inclua uma atualização para arquivos compactados, se a compactação estiver em uso:

<mimeMap fileExtension=".bin.br" mimeType="application/octet-stream" />
<mimeMap fileExtension=".bin.gz" mimeType="application/octet-stream" />

Remova a entrada para a extensão de arquivo .dll:

- <mimeMap fileExtension=".dll" mimeType="application/octet-stream" />

Remova as entradas para arquivos .dll compactados, se a compactação estiver em uso:

- <mimeMap fileExtension=".dll.br" mimeType="application/octet-stream" />
- <mimeMap fileExtension=".dll.gz" mimeType="application/octet-stream" />

Para obter mais informações sobre arquivos web.config personalizados, confira a seção Usar um web.config personalizado.

Dano antes da implantação

Normalmente na implantação:

  • Somente os arquivos que foram alterados são substituídos, o que geralmente resulta em uma implantação mais rápida.
  • Os arquivos existentes que não fazem parte da nova implantação são deixados no lugar para serem usados pela nova implantação.

Em casos raros, os arquivos remanescentes de uma implantação anterior podem corromper uma nova implantação. Excluir completamente a implantação existente (ou aplicativo publicado localmente antes da implantação) pode resolver o problema com uma implantação corrompida. Geralmente, excluir a implantação existente uma vez é suficiente para resolver o problema, inclusive para um pipeline de build e implantação do DevOps.

Se você determinar que a limpeza de uma implantação anterior é sempre necessária quando um pipeline de build e implantação do DevOps está em uso, você pode adicionar temporariamente uma etapa ao pipeline de build para excluir a implantação anterior para cada nova implantação, até que você solucione a causa exata do dano.

Resolver falhas de verificação de integridade

Quando o Blazor WebAssembly baixa os arquivos de inicialização de um aplicativo, ele instrui o navegador a executar verificações de integridade nas respostas. Blazor envia os valores de hash SHA-256 para DLL (.dll), WebAssembly (.wasm) e outros arquivos no arquivo blazor.boot.json, que não são armazenados em cache nos clientes. Os hashes de arquivos armazenados em cache são comparados aos hashes no arquivo blazor.boot.json. Para arquivos armazenados em cache com um hash correspondente, Blazor usa os arquivos armazenados em cache. Caso contrário, os arquivos serão solicitados do servidor. Depois que um arquivo é baixado, o hash é verificado novamente para validação de integridade. Um erro será gerado pelo navegador, em caso de falha na verificação de integridade de qualquer arquivo baixado.

O algoritmo do Blazor para gerenciar a integridade do arquivo:

  • Garante que o aplicativo não corre o risco de carregar um conjunto inconsistente de arquivos, por exemplo, se uma nova implantação for aplicada ao servidor Web, enquanto o usuário estiver em processo de download dos arquivos do aplicativo. Os arquivos inconsistentes podem resultar em um aplicativo com defeito.
  • Garante que o navegador do usuário nunca armazene em cache respostas inconsistentes ou inválidas, o que pode impedir que o aplicativo seja iniciado mesmo que o usuário atualize a página manualmente.
  • Torna seguro armazenar em cache as respostas e não verificar quanto a alterações do lado do servidor até que os hashes SHA-256 esperados sejam alterados. Portanto, as cargas de página subsequentes envolvem menos solicitações e são concluídas mais rapidamente.

Se o servidor Web retornar respostas que não correspondem aos hashes SHA-256 esperados, um erro semelhante ao exemplo a seguir será exibido no console do desenvolvedor do navegador:

Falha ao localizar um código hash válido no atributo 'integrity' para o 'https://myapp.example.com/_framework/MyBlazorApp.dll' do recurso com a integridade SHA-256 calculada 'IIa70iwvmEg5WiDV17OpQ5eCztNYqL186J56852RpJY='. O recurso foi bloqueado.

Na maioria dos casos, o aviso não indica um problema na verificação de integridade. Em vez disso, o aviso geralmente significa que existe algum outro problema.

Para obter a origem de referência de inicialização do Blazor WebAssembly, confira arquivo Boot.WebAssembly.ts no dotnet/aspnetcorerepositório GitHub.

Observação

Os links de documentação para a fonte de referência do .NET geralmente carregam o branch padrão do repositório, que representa o desenvolvimento atual da próxima versão do .NET. Para selecionar uma marca para uma versão específica, use a lista suspensa para Alternar branches ou marcas. Para saber mais, confira Como selecionar uma marca de versão do código-fonte do ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Como diagnosticar problemas de integridade

Quando um aplicativo é criado, o manifesto blazor.boot.json gerado descreve os hashes SHA-256 dos recursos de inicialização no momento em que a saída do build é produzida. A verificação de integridade é aprovada desde que os hashes SHA-256 no blazor.boot.json correspondam aos arquivos entregues ao navegador.

Motivos comuns para dessa falha incluem:

  • A resposta do servidor Web é um erro (por exemplo, 404 – Não Encontrado ou 500 – Erro do Servidor Interno), em vez do arquivo solicitado pelo navegador. Isso é relatado pelo navegador como uma falha na verificação de integridade e não como falha de resposta.
  • Algo alterou o conteúdo dos arquivos entre o build e a entrega dos arquivos no navegador. Isso pode acontecer:
    • Se você ou as ferramentas de build modificarem manualmente a saída do build.
    • Se algum aspecto do processo de implantação tiver modificado os arquivos. Por exemplo, se você usar um mecanismo de implantação baseado em Git, tenha em mente que o Git converte de forma transparente as terminações de linha no estilo Windows em terminações de linha no estilo Unix, se você confirmar os arquivos no Windows e marcá-los no Linux. Alterar as terminações de linha de arquivo altera os hashes SHA-256. Para evitar esse problema, use .gitattributes para tratar artefatos de build como arquivos binary.
    • O servidor Web modifica o conteúdo do arquivo como parte do serviço. Por exemplo, algumas CDNs (redes de distribuição de conteúdo) tentam minificar o HTML automaticamente, modificando-o. Talvez seja necessário desabilitar esses recursos.
  • O arquivo blazor.boot.json não é carregado corretamente ou é armazenado em cache incorretamente no cliente. As causas comuns incluem uma das seguintes opções:
    • Código de desenvolvedor personalizado configurado incorretamente ou com defeito.
    • Uma ou mais camadas de cache intermediárias configuradas incorretamente.

Para diagnosticar qual dessas opções se aplica ao seu caso:

  1. Observe qual arquivo está disparando o erro, lendo a mensagem de erro.
  2. Abra as ferramentas de desenvolvedor no navegador e dê uma olhada na guia Rede. Se necessário, recarregue a página para ver a lista de solicitações e respostas. Localize o arquivo que está disparando o erro nessa lista.
  3. Verifique o código de status HTTP na resposta. Se o servidor retornar algo diferente de 200 – OK (ou outro código de status 2xx), significa que há um problema no lado do servidor para diagnosticar. Por exemplo, o código de status 403 significa que há um problema de autorização, enquanto o código de status 500 significa que o servidor está falhando de maneira não especificada. Veja os logs do lado do servidor para diagnosticar e corrigir o aplicativo.
  4. Se o código de status for 200 – OK para o recurso, examine o conteúdo da resposta nas ferramentas de desenvolvedor do navegador e verifique se o conteúdo corresponde aos dados esperados. Por exemplo, um problema comum é configurar incorretamente o roteamento de modo que as solicitações retornem os dados do index.html até mesmo para outros arquivos. Verifique se as respostas às solicitações do .wasm são binários do WebAssembly e se as respostas às solicitações do .dll são binários de assembly do .NET. Caso contrário, significa que há um problema de roteamento do lado do servidor para diagnosticar.
  5. Procure validar a saída publicada e implantada do aplicativo com o script do PowerShell Solucionar problemas de integridade.

Se você confirmar que o servidor está retornando dados plausivelmente corretos, deve haver outra coisa modificando o conteúdo entre o build e a entrega do arquivo. Para investigar isso:

  • Examine a cadeia de ferramentas de build e o mecanismo de implantação, caso estejam modificando os arquivos depois que os arquivos são compilados. Um exemplo disso é quando o Git transforma as terminações de linha de arquivo, conforme descrito anteriormente.
  • Examine o servidor Web ou a configuração da CDN, caso estejam configurados para modificar as respostas dinamicamente (por exemplo, tentando minificar o HTML). Não há problema se o servidor Web implementa a compactação HTTP (por exemplo, retornando content-encoding: br ou content-encoding: gzip), pois isso não afeta o resultado após a descompactação. No entanto, problema se o servidor Web modifica os dados descompactados.

Script do PowerShell Solucionar problemas de integridade

Use o script do PowerShell integrity.ps1 para validar um aplicativo Blazor publicado e implantado. O script é fornecido para o PowerShell Core 7 ou posterior como ponto de partida, quando o aplicativo tem problemas de integridade que a estrutura Blazor não pode identificar. A personalização do script pode ser necessária para seus aplicativos, incluindo se estiver em execução na versão do PowerShell posterior à versão 7.2.0.

O script verifica os arquivos na pasta publish e baixados pelo aplicativo implantado para detectar problemas nos diferentes manifestos que contêm hashes de integridade. Essas verificações devem detectar os problemas mais comuns:

  • Você modificou um arquivo na saída publicada sem perceber.
  • O aplicativo não foi implantado corretamente no destino de implantação ou algo foi alterado no ambiente do destino de implantação.
  • Há diferenças entre o aplicativo implantado e a saída da publicação do aplicativo.

Invoque o script com o seguinte comando em um shell de comando do PowerShell:

.\integrity.ps1 {BASE URL} {PUBLISH OUTPUT FOLDER}

No exemplo a seguir, o script é executado em um aplicativo em execução local em https://localhost:5001/:

.\integrity.ps1 https://localhost:5001/ C:\TestApps\BlazorSample\bin\Release\net6.0\publish\

Espaços reservados:

  • {BASE URL}: a URL do aplicativo implantado. A barra à direita (/) é necessária.
  • {PUBLISH OUTPUT FOLDER}: o caminho para a pasta ou o local publish do aplicativo em que o aplicativo é publicado para implantação.

Observação

Ao clonar o repositório GitHub dotnet/AspNetCore.Docs, o script integrity.ps1 pode ser colocado em quarentena pelo Bitdefender ou por outro verificador de vírus presente no sistema. Normalmente, o arquivo é interceptado pela tecnologia de verificação heurística de um verificador de vírus, que apenas procura padrões em arquivos que podem indicar a presença de malware. Para impedir que o verificador de vírus coloque o arquivo em quarentena, adicione uma exceção ao verificador de vírus antes de clonar o repositório. O exemplo a seguir é um caminho típico para o script em um sistema Windows. Ajuste o caminho conforme necessário para outros sistemas. O espaço reservado {USER} é o segmento de caminho do usuário.

C:\Users\{USER}\Documents\GitHub\AspNetCore.Docs\aspnetcore\blazor\host-and-deploy\webassembly\_samples\integrity.ps1

Aviso: criar exceções no verificador de vírus é perigoso e isso só deve ser feito quando você tiver certeza de que o arquivo está seguro.

Comparar a soma de verificação de um arquivo com um valor de soma de verificação válido não garante a segurança do arquivo, mas modificar um arquivo de forma a manter um valor de soma de verificação não é trivial para usuários mal-intencionados. Portanto, as somas de verificação são úteis como uma abordagem de segurança geral. Compare a soma de verificação do arquivo local integrity.ps1 com um dos seguintes valores:

  • SHA256: 32c24cb667d79a701135cb72f6bae490d81703323f61b8af2c7e5e5dc0f0c2bb
  • MD5: 9cee7d7ec86ee809a329b5406fbf21a8

Obtenha a soma de verificação do arquivo no sistema operacional Windows com o comando a seguir. Forneça o caminho e o nome do arquivo para o espaço reservado {PATH AND FILE NAME} e indique o tipo de soma de verificação a ser produzida para o espaço reservado {SHA512|MD5}, SHA256 ou MD5:

CertUtil -hashfile {PATH AND FILE NAME} {SHA256|MD5}

Se você tiver algum motivo para se preocupar com o fato de que a validação da soma de verificação não é segura o suficiente no seu ambiente, consulte a liderança de segurança da sua organização para obter diretrizes.

Para obter mais informações, confira Visão geral da proteção contra ameaças pelo Microsoft Defender Antivírus.

Desabilitar a verificação de integridade para aplicativos não PWA

Na maioria dos casos, não desabilite a verificação de integridade. Desabilitar a verificação de integridade não resolve o problema subjacente que causou as respostas inesperadas e resulta na perda dos benefícios listados anteriormente.

Pode haver casos em que o servidor Web não pode ser invocado para retornar respostas consistentes e você não tem escolha a não ser desabilitar temporariamente as verificações de integridade até que o problema subjacente seja resolvido.

Para desabilitar as verificações de integridade, adicione o seguinte a um grupo de propriedades no arquivo de projeto do aplicativo Blazor WebAssembly (.csproj):

<BlazorCacheBootResources>false</BlazorCacheBootResources>

BlazorCacheBootResources também desabilita o comportamento padrão do Blazor de armazenar em cache os arquivos .dll, .wasm e outros arquivos com base nos hashes SHA-256, pois a propriedade indica que os hashes SHA-256 não podem ser considerados corretos. Mesmo com essa configuração, o cache HTTP normal do navegador ainda pode armazenar em cache esses arquivos, mas se isso acontecerá ou não depende da configuração do servidor Web e dos cabeçalhos cache-control atendidos.

Observação

A propriedade BlazorCacheBootResources não desabilita as verificações de integridade para PWAs (Aplicativos Web Progressivos). Para obter diretrizes relativas aos PWAs, confira a seção Desabilitar verificação de integridade para PWAs.

Não é possível fornecer uma lista completa de cenários em que é necessário desabilitar a verificação de integridade. Os servidores podem responder a uma solicitação de maneiras arbitrárias fora do escopo da estrutura Blazor. A estrutura fornece a configuração BlazorCacheBootResources para tornar o aplicativo executável às custas de perder a garantia de integridade que o aplicativo pode fornecer. Novamente, não recomendamos desabilitar a verificação de integridade, especialmente para implantações de produção. Os desenvolvedores devem procurar resolver o problema de integridade subjacente que está causando falha na verificação de integridade.

Alguns casos gerais que podem causar problemas de integridade são:

  • Em execução em HTTP, onde a integridade não pode ser verificada.
  • Se o processo de implantação modificar os arquivos após a publicação de alguma forma.
  • Se o host modificar os arquivos de alguma forma.

Desabilitar a verificação de integridade para PWAs

O modelo de PWA (Aplicativo Web Progressivo) do Blazor contém um arquivo service-worker.published.js sugerido, que é responsável por buscar e armazenar arquivos de aplicativo para uso offline. Esse é um processo separado do mecanismo normal de inicialização do aplicativo e tem sua própria lógica de verificação de integridade separada.

Dentro do arquivo service-worker.published.js, a seguinte linha está presente:

.map(asset => new Request(asset.url, { integrity: asset.hash }));

Para desabilitar a verificação de integridade, remova o parâmetro integrity alterando a linha para o seguinte:

.map(asset => new Request(asset.url));

Novamente, desabilitar a verificação de integridade significa que você perderá as garantias de segurança oferecidas pela verificação de integridade. Por exemplo, existe o risco de que, se o navegador do usuário estiver armazenando em cache o aplicativo no momento exato em que você implantar uma nova versão, ele poderá armazenar em cache alguns arquivos da implantação antiga e outros da nova implantação. Se isso acontecer, o aplicativo ficará paralisado em um estado interrompido até que você implante uma nova atualização.