Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Por Rick Anderson
Arquivos estáticos, como HTML, CSS, imagens e JavaScript, são ativos que um aplicativo ASP.NET Core fornece diretamente para os clientes por padrão.
Para obter Blazor diretrizes de arquivos estáticos, que adiciona ou substitui as diretrizes neste artigo, consulte Arquivos estáticos do ASP.NET Core Blazor.
Servir arquivos estáticos
Os arquivos estáticos são armazenados no diretório raiz Web do projeto. O diretório padrão é {content root}/wwwroot
, mas pode ser alterado com o método UseWebRoot. Para obter mais informações, consulte Raiz de conteúdo e Raiz web.
O método CreateBuilder define a raiz do conteúdo como o diretório atual:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.MapStaticAssets();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
Os arquivos estáticos são acessíveis por meio de um caminho relativo à raiz Web. Por exemplo, os modelos de projeto do Aplicativo Web contêm várias pastas dentro da pasta wwwroot
:
wwwroot
css
js
lib
Considere um aplicativo com o wwwroot/images/MyImage.jpg
arquivo. O formato de URI para acessar um arquivo na pasta images
é https://<hostname>/images/<image_file_name>
. Por exemplo, https://localhost:5001/images/MyImage.jpg
Convenções de ponto de extremidade de encaminhamento de Mapear Ativos Estáticos (MapStaticAssets
)
A criação de aplicativos Web com bom desempenho requer a otimização do fornecimento de ativos ao navegador. As possíveis otimizações com MapStaticAssets incluem:
- Sirva um determinado ativo uma vez até que o arquivo seja alterado ou o navegador limpe seu cache. Defina os cabeçalhos ETag e Last-Modified .
- Impedir que o navegador use ativos antigos ou obsoletos depois que um aplicativo for atualizado. Definir o cabeçalho Last-Modified.
- Configurar os cabeçalhos de cache adequadamente.
- Use o Middleware de Cache.
- Fornecer versões comprimidas dos ativos quando possível. Essa otimização não inclui a minificação.
- Use um CDN para distribuir os conteúdos mais próximos do usuário.
- Ativos de impressão digital para evitar reutilizações de versões antigas de arquivos.
MapStaticAssets
:
- Integra as informações coletadas sobre ativos da Web estáticos durante o processo de compilação e publicação com uma biblioteca de runtime que processa essas informações para otimizar o serviço de arquivos para o navegador.
- São convenções de pontos de extremidade de roteamento que otimizam a entrega de ativos estáticos no aplicativo. Ele foi projetado para funcionar com todas as estruturas de interface do usuário, incluindo Blazor, Razor Pages e MVC.
MapStaticAssets
contra UseStaticFiles
MapStaticAssets está disponível no ASP.NET Core no .NET 9 ou posterior. UseStaticFiles deve ser usado em versões anteriores ao .NET 9.
UseStaticFiles
serve arquivos estáticos, mas não fornece o mesmo nível de otimização que MapStaticAssets
. MapStaticAssets
é otimizado para atender ativos dos quais o aplicativo tem conhecimento no runtime. Se o aplicativo atender ativos de outros locais, como disco ou recursos inseridos, o UseStaticFiles
deverá ser usado.
O Mapa de Ativos Estáticos fornece os seguintes benefícios que não estão disponíveis ao chamar UseStaticFiles
:
- Compactação no tempo de compilação para todos os recursos no aplicativo, incluindo JavaScript (JS) e folhas de estilo, mas excluindo recursos de imagem e fonte que já estão compactados. A compactação Gzip (
Content-Encoding: gz
) é usada durante o desenvolvimento. A compactação Gzip com Brotli (Content-Encoding: br
) é usada durante a publicação. - Impressão Digital para todos os ativos em tempo de compilação com uma cadeia de caracteres codificada em Base64do hash SHA-256 do conteúdo de cada arquivo. Isso impede a reutilização de uma versão antiga de um arquivo, mesmo que o arquivo antigo seja armazenado em cache. Os ativos com impressão digital são armazenados em cache usando a
immutable
diretiva, o que faz com que o navegador nunca mais solicite o ativo até que ele seja alterado. Para navegadores que não dão suporte àimmutable
diretiva, umamax-age
diretiva é adicionada.- Mesmo que um ativo não seja fingerprintado, o conteúdo baseado em
ETags
é gerado para cada ativo estático usando o hash de impressão digital do arquivo como valorETag
. Isso garante que o navegador baixe apenas um arquivo se o conteúdo for alterado (ou se o arquivo estiver sendo baixado pela primeira vez). - Internamente, a estrutura mapeia ativos físicos para suas impressões digitais, o que permite ao aplicativo:
- Encontre ativos gerados automaticamente, como Razor CSS com escopo de componente para o Blazorrecurso de isolamento CSS e ativos JS descritos por JS mapas de importação.
- Gere tags de link no conteúdo
<head>
da página para pré-carregar recursos.
- Mesmo que um ativo não seja fingerprintado, o conteúdo baseado em
- Durante os testes de desenvolvimento de Recarga Dinâmica do Visual Studio:
- As informações de integridade são removidas dos ativos para evitar problemas quando um arquivo é alterado enquanto o aplicativo está em execução.
- Os ativos estáticos não são armazenados em cache para garantir que o navegador sempre recupere o conteúdo atual.
O Mapa de Ativos Estáticos não fornece recursos para minificação ou outras transformações de arquivo. A minificação geralmente é feita com código personalizado ou ferramentas de terceiros.
Os seguintes recursos têm suporte com UseStaticFiles
, mas não com MapStaticAssets
:
- Servindo arquivos a partir do disco, de recursos embutidos, ou de outros locais
- Fornecer arquivos fora do diretório base
- Definir cabeçalhos de resposta HTTP
- Navegação de diretório
- Fornecer documentos padrão
FileExtensionContentTypeProvider
- Servir arquivos de vários locais
- Servindo arquivos a partir do disco, de recursos embutidos, ou de outros locais
- Fornecer arquivos fora do diretório base
- Definir cabeçalhos de resposta HTTP
- Navegação de diretório
- Fornecer documentos padrão
FileExtensionContentTypeProvider
- Servir arquivos de vários locais
Fornecer arquivos na raiz Web
Os templates de aplicativo Web padrão chamam o método MapStaticAssets no Program.cs
, que permite que arquivos estáticos sejam servidos.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.MapStaticAssets();
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
A sobrecarga do método MapStaticAssets
sem parâmetro marca os arquivos raiz Web como fornecíveis. As seguintes referências de marcação wwwroot/images/MyImage.jpg
:
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
Na marcação anterior, o caractere ~
de til aponta para a raiz Web.
Fornecer arquivos fora do diretório base
Considere uma hierarquia de diretórios na qual os arquivos estáticos a serem fornecidos residam fora da raiz Web:
wwwroot
css
images
js
MyStaticFiles
images
red-rose.jpg
Uma solicitação pode acessar o arquivo red-rose.jpg
configurando o middleware de arquivo estático da seguinte maneira:
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles(); //Serve files from wwwroot
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
No código anterior, a hierarquia de diretórios MyStaticFiles é exposta publicamente por meio do segmento do URI StaticFiles. Uma solicitação para https://<hostname>/StaticFiles/images/red-rose.jpg
fornece ao arquivo red-rose.jpg
.
As seguintes referências de marcação MyStaticFiles/images/red-rose.jpg
:
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />
Para fornecer arquivos de vários locais, consulte Fornecer arquivos de vários locais.
Definir cabeçalhos de resposta HTTP
Um objeto StaticFileOptions pode ser usado para definir cabeçalhos de resposta HTTP. Além de configurar a distribuição de arquivos estáticos a partir da Raiz Web, o código a seguir define o cabeçalho Cache-Control:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
}
});
app.UseAuthorization();
app.MapDefaultControllerRoute().WithStaticAssets();
app.MapRazorPages().WithStaticAssets();
app.Run();
O código anterior disponibiliza arquivos estáticos publicamente no cache local por uma semana.
Autorização de arquivo estático
Os modelos de ASP.NET Core chamam MapStaticAssets antes de chamar UseAuthorization. A maioria dos aplicativos segue esse padrão. Quando MapStaticAssets
é chamado antes do middleware de autorização:
- Nenhuma verificação de autorização é executada nos arquivos estáticos.
- Os arquivos estáticos fornecidos pelo Middleware de arquivo estático, como aqueles em
wwwroot
, são acessíveis publicamente.
Para fornecer arquivos estáticos com base na autorização, consulte a autorização de arquivo estático.
Servir arquivos de vários locais
Considere a seguinte página Razor que exibe o arquivo /MyStaticFiles/image3.png
:
@page
<p> Test /MyStaticFiles/image3.png</p>
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">
UseStaticFiles
e UseFileServer
padrão para o provedor de arquivos apontando para wwwroot
. Instâncias adicionais de UseStaticFiles
e UseFileServer
podem ser fornecidas com outros provedores de arquivos para fornecer arquivos de outros locais. O exemplo a seguir chama UseStaticFiles
duas vezes para fornecer arquivos de wwwroot
e MyStaticFiles
:
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"))
});
Usando o código anterior:
- O arquivo
/MyStaticFiles/image3.png
é exibido. - Os auxiliares de marcação de imagemAppendVersion não são aplicados porque os auxiliares de marcação dependem de WebRootFileProvider.
WebRootFileProvider
não foi atualizado para incluir a pastaMyStaticFiles
.
O código a seguir atualiza o WebRootFileProvider
, o que permite que o Image Tag Helper forneça uma versão:
var webRootProvider = new PhysicalFileProvider(builder.Environment.WebRootPath);
var newPathProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"));
var compositeProvider = new CompositeFileProvider(webRootProvider,
newPathProvider);
// Update the default provider.
app.Environment.WebRootFileProvider = compositeProvider;
app.MapStaticAssets();
Observação
A abordagem anterior se aplica a Razor Pages e aplicativos MVC. Para obter diretrizes que se aplicam aos Blazor Web Apps, consulte Arquivos estáticos do ASP.NET Core Blazor.
Servir arquivos fora de wwwroot ao atualizar IWebHostEnvironment.WebRootPath
Quando IWebHostEnvironment.WebRootPath é definido como uma pasta diferente de wwwroot
:
- No ambiente de desenvolvimento, os ativos estáticos encontrados tanto em
wwwroot
quanto nos atualizadosIWebHostEnvironment.WebRootPath
são fornecidos a partir dewwwroot
. - Em qualquer ambiente que não seja de desenvolvimento, os recursos estáticos duplicados são servidos da pasta atualizada
IWebHostEnvironment.WebRootPath
.
Considere um aplicativo Web criado com o modelo da Web vazio:
Contendo um arquivo
Index.html
emwwwroot
ewwwroot-custom
.Com o seguinte arquivo
Program.cs
atualizado que defineWebRootPath = "wwwroot-custom"
:var builder = WebApplication.CreateBuilder(new WebApplicationOptions { Args = args, // Look for static files in "wwwroot-custom" WebRootPath = "wwwroot-custom" }); var app = builder.Build(); app.UseDefaultFiles(); app.MapStaticAssets(); app.Run();
No código anterior, solicitações para /
:
- No ambiente de desenvolvimento retorna
wwwroot/Index.html
- Em qualquer ambiente que não seja o retorno do desenvolvimento
wwwroot-custom/Index.html
Para garantir que os ativos de wwwroot-custom
sejam retornados, use uma das seguintes abordagens:
Exclua ativos nomeados duplicados em
wwwroot
.Defina
"ASPNETCORE_ENVIRONMENT"
emProperties/launchSettings.json
para qualquer valor diferente de"Development"
.Desabilite completamente os ativos da Web estáticos definindo
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
no arquivo de projeto. AVISO, desabilitar ativos da Web estáticos desabilita Razor bibliotecas de classes.Adicione o seguinte XML ao arquivo de projeto:
<ItemGroup> <Content Remove="wwwroot\**" /> </ItemGroup>
O código a seguir atualiza IWebHostEnvironment.WebRootPath
para um valor que não é de desenvolvimento, garantindo que o conteúdo duplicado seja retornado de wwwroot-custom
ao invés de wwwroot
:
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Examine Hosting environment: logging value
EnvironmentName = Environments.Staging,
WebRootPath = "wwwroot-custom"
});
var app = builder.Build();
app.Logger.LogInformation("ASPNETCORE_ENVIRONMENT: {env}",
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
app.Logger.LogInformation("app.Environment.IsDevelopment(): {env}",
app.Environment.IsDevelopment().ToString());
app.UseDefaultFiles();
app.MapStaticAssets();
app.Run();