此文是在官方文档的基础上做的个人笔记,一些简单的内容就没用再列出来了,参考官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/static-files?view=aspnetcore-5.0
默认情况下,诸如HTML、css、图像、js之类的静态资源,应用不需要特殊处理直接提供出去。静态资源一般都存放在wwwroot
文件夹中。
1.提供静态文件
1.1 提供wwwroot
目录下的静态文件
直接调用app.UseStaticFiles()
.
1.2 提供wwwroot
目录及以外的静态文件访问
//可以访问wwwroot下的静态文件
app.UseStaticFiles();
//可以访问其他目录下的文件
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "MyStaticFiles")),
RequestPath = "/StaticFiles",
OnPrepareResponse=ctx=>
{
//还可以添加额外响应头
ctx.Context.Response.Headers.Append("Cache-control",$"public, max-age=604800");
}
});
这样通过http://xxx.com/staticfiles/image/1.jpg
就可以请求到MyStaticFiles
下的文件。
2.静态文件的访问权限
一般情况下UseStaticFiles
是放在UseAuthorization
前面的,所以是谁都可以访问的。如果前面例子中MyStaticFiles中存在一些需要授权才能访问的文件,你就可以把UseAuthorization
放到UseStaticFiles(xxxx)
前面,然后设置回退授权策略。
//可以访问wwwroot下的静态文件
app.UseStaticFiles();
app.UseAuthorization();//需要授权
//可以访问其他目录下的文件
app.UseStaticFiles(new StaticFileOptions{.....});
然后在startup中设置回退策略
services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
RequireAuthenticateUser
要求所有试图访问的用户都必须被认证通过。即使某些controller、action上指定了[AllowAnonyous]、[Authorize(PolicyName="MyPolicy")]
也不行。
另外一种实现授权访问的方法是在Action中直接返回一个PhysicalFile
:
[Authorize]
public IActionResult BannerImage()
{
var filePath = Path.Combine(_env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
3.目录浏览
处于安全考虑,目录浏览默认被禁用。通过以下方法可以开启目录浏览:
configureServices
里添加AddDirectoryBrowser
configure
里添加UseDirectoryBrowser
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDirectoryBrowser();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//提供静态文件访问
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
//提供目录浏览
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages"
});
}
4. 默认静态文件页
应用场景:若要访问某个静态文件,一般要输入完整的url或者开启目录浏览。当然也可以通过UseDefaultFiles
方法,在不输入完整url的情况下指定一个默认的静态文件。必须在UseStaticFiles
之前调用UseDefaultFiles
。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//...
app.UseDefaultFiles();
app.UseStaticFiles();
//...
}
UseDefaultFiles
会在wwwroot中搜索以下几项,先找到哪个就返回哪个的内容:
- default.htm
- default.html
- index.htm
- index.html
当然也可以传入一个参数用来设置默认搜索的文件名,
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();
4.1 UseFileServer
作用:相当于是UseStaticFiles
和UseDefaultFiles
的结合。而且也可以配合UseDirectoryBrowser
使用。
下面代码演示了UseFileServer和UseDriectoryBrowser的结合使用
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//...
app.UseFileServer(enableDirectoryBrowsing: true);
//...
}
5. FileExtensionContentTypeProvider
作用:设置静态文件的MIME类型。
var provider = new FileExtensionContentTypeProvider();
//添加新的映射
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";
//替换已有的映射
provider.Mappings[".rtf"] = "application/x-msdownload";
//移除映射
provider.Mappings.Remove(".mp4");
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.WebRootPath, "images")),
RequestPath = "/MyImages",
ContentTypeProvider = provider//设置provider
});
MIME大全:https://www.iana.org/assignments/media-types/media-types.xhtml
6.非标准内容类型
静态文件中间件可以理解大约400种已知文件的内容类型。如果用户请求的文件类型中间件理解不了,就会把请求传递给管道中的后续中间件,如果后续的中间件没有一个能处理这个请求,那么就会返回404。以下代码表示中间件将所有理解不了的文件都以图像形式返回:
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});
注意:ServeUnknownFileTypes
会造成安全隐患,引起文件泄露。所以默认是禁用的,不建议使用。如果真的没法满足需求,请考虑使用前面介绍的FileExtensionContentTypeProvider
。