静态文件(static files),诸如 HTML、CSS、图片和 JavaScript 之类的资源会被 ASP.NET Core 应用直接提供给客户端。

静态文件服务

// 安装 StaticFiles 包
Install-Package Microsoft.AspNetCore.StaticFiles

在应用程序中,我们可以通过配置 StaticFiles 中间件来启用静态文件服务,将 StaticFiles 中间件加入到管道中:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseStaticFiles(); 
}

静态文件通常位于 web root(/wwwroot)文件夹下。我们通常会把项目的当前目录设置为 content root,这样项目的 web root 就可以在开发阶段被明确。

  • http://(app)/(fileName)
  • http://localhost:9189/1.jpg
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseStaticFiles(new StaticFileOptions()
    {
        FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"MyStaticFiles")),
        RequestPath = new PathString("/StaticFiles")
    });
}

静态文件也可以保存在网站根目录下的任意文件夹内,可以通过相对根路径来访问。

  • http://(app)/StaticFiles/(fileName)
  • http://localhost:9189/StaticFiles/1.jpg

设置响应标头

StaticFileOptions() 可以设置响应标头。例如,下面的代码设置静态文件服务使用 wwwroot 文件夹和设置 Cache-Control 让静态资源缓存10分钟(600秒):

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(new StaticFileOptions()
    {
        OnPrepareResponse = ctx =>
        {
            ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=600");
        }
    });
}

HeaderDictionaryExtensions.Append 扩展方法可以通过安装 Microsoft.AspNetCore.Http 包来使用。

启用目录浏览

DirectoryBrowser 允许网站用户看到指定目录下的目录和文件列表。基于安全考虑,默认情况下是禁用目录访问功能的。在 Startup.Configure 中调用 UseDirectoryBrowser 扩展方法可以开启网络应用目录浏览:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseDirectoryBrowser(new DirectoryBrowserOptions()
    {
        FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"MyStaticFiles")),
        RequestPath = new PathString("/StaticFiles")
    });
}

Startup.ConfigureServices 中调用所需要的服务 AddDirectoryBrowser

public void ConfigureServices(IServiceCollection services)
{
    services.AddDirectoryBrowser();
}

上面的代码允许访问 StaticFiles 文件中的所有文件和文件夹的链接:

提供一个默认文件

通过在 Startup.Configure 调用 UseDefaultFiles 可以为站点配置一个默认页面。

public void Configure(IApplicationBuilder app)
{
    app.UseDefaultFiles();
    app.UseStaticFiles();
}

必须在调用 UseStaticFiles 之前 UseDefaultFilesUseDefaultFiles 只是一个 URL 重写,实际上并不提供文件,文件的提供必须使用 StaticFiles 中间件。

使用 UseDefaultFiles 默认搜索的文件:

  • default.htm
  • default.html
  • index.htm
  • index.html

下面的代码演示了如何将默认文件设置为 mydefault.html

public void Configure(IApplicationBuilder app)
{
    // Serve my app-specific default file, if present.
    DefaultFilesOptions options = new DefaultFilesOptions();
    options.DefaultFileNames.Clear();
    options.DefaultFileNames.Add("mydefault.html");
    app.UseDefaultFiles(options);
    app.UseStaticFiles();
}

文件服务器

UseFileServer 的功能结合了 UseStaticFiles, UseDefaultFiles, UseDirectoryBrowser

下面的代码允许访问静态文件和默认文件,但不允许浏览目录:

app.UseFileServer();

下面的代码允许访问静态文件,默认文件和目录浏览:

app.UseFileServer(enableDirectoryBrowsing: true);

如果想要有一个静态文件服务器在 web root 之外,可以配置静态文件中间件:

public void Configure(IApplicationBuilder app)
{
    app.UseFileServer(new FileServerOptions()
    {
        FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"MyStaticFiles2")),
        RequestPath = new PathString("/StaticFiles2")
    });
}

EnableDirectoryBrowsing 设置为 true 时,开启目录浏览:

public void Configure(IApplicationBuilder app)
{
    app.UseFileServer(new FileServerOptions()
    {
        FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"MyStaticFiles2")),
        RequestPath = new PathString("/StaticFiles2"),
        EnableDirectoryBrowsing = true
    });
}

并且需要在 Startup.ConfigureServices 中调用所需要的服务 AddDirectoryBrowser

public void ConfigureServices(IServiceCollection services)
{
    services.AddDirectoryBrowser();
}

FileExtensionContentTypeProvider

FileExtensionContentTypeProvider 类包含一个将文件扩展名映射到 MIME 内容类型的集合。在下面的例子中,多个文件扩展名注册为已知的 MIME 类型,“.rtf”被替换,“.mp4”被移除。

public void ConfigureServices(IServiceCollection services)
{
    // Set up custom content types -associating file extension to MIME type
    var provider = new FileExtensionContentTypeProvider();
    // Add new mappings
    provider.Mappings[".myapp"] = "application/x-msdownload";
    provider.Mappings[".htm3"] = "text/html";
    provider.Mappings[".image"] = "image/png";
    // Replace an existing mapping
    provider.Mappings[".rtf"] = "application/x-msdownload";
    // Remove MP4 videos.
    provider.Mappings.Remove(".mp4");

    app.UseStaticFiles(new StaticFileOptions()
    {
        FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"MyStaticFiles3")),
        RequestPath = new PathString("/StaticFiles3"),
        ContentTypeProvider = provider
    });
}

查看 MIME 内容类型

非标准的内容类型

ASP.NET Core StaticFiles 中间件能够支持超过 400 种已知文件内容类型。如果用户请求一个未知的文件类型,静态文件中间件将返回 HTTP 404(未找到)响应。如果启用目录浏览,该文件的链接将会被显示,但 URI 会返回一个 HTTP 404 错误。

下面的代码把不能识别的类型和文件作为图片处理:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseStaticFiles(new StaticFileOptions
    {
        ServeUnknownFileTypes = true,
        DefaultContentType = "image/png"
    });
}

根据上面的代码,未知内容类型的文件请求将返回一张图片。

注意事项

开启 ServeUnknownFileTypes 存在安全风险,请打消这个念头。 FileExtensionContentTypeProvider (下文将解释)提供了更安全的非标准扩展替代。
UseDirectoryBrowserUseStaticFiles 可能会泄密。 不要 在生产环境开启目录浏览。要小心哪些开启了 UseStaticFilesUseDirectoryBrowser 的目录(使得其子目录都可被访问)。建议将公开内容放在诸如 /wwwroot 这样的目录中,远离应用程序视图、配置文件等。

  • 使用 UseDirectoryBrowser 和 UseStaticFiles 暴露的文件的 URL 是否区分大小写以及字符限制受制于底层文件系统。比方说 Windows 是不区分大小写的,但 macOS 和 Linux 则区分大小写。
  • 托管于 IIS 的 ASP.NET Core 应用程序使用 ASP.NET Core 模块向应用程序转发所有请求,包括静态文件。IIS 静态文件处理程序(IIS Static File Handler)不会被使用,因为在 ASP.NET Core 模块处理之前它没有任何机会来处理请求。
  • 以下步骤可移除 IIS 静态文件处理程序(在服务器层级或网站层级上):
    1.导航到模块功能
    2.从列表中选中 StaticFileModule
    3.在操作侧边栏中点击删除

如果 IIS 静态文件处理程序开启 并且 ASP.NET Core 模块(ANCM)没有被正确配置(比方说 web.config 没有部署),(也能)将会提供静态文件。

  • 代码文件(包括 C# 和 Razor)应该放在应用程序项目的 web root (默认为 wwwroot)之外的地方。这将确保您创建的应用程序能明确隔离客户端侧和服务器侧源代码,此举能防止服务器侧的代码被泄露。

全部评论

发一条友善的评论... 取消回复

提醒 : 您所填写的邮箱地址不会被公开!

看不清?点击更换