《ASP.NET Core 高性能系列》静态文件中间件

一、概述

  静态文件(如 HTML、CSS、图片和 JavaScript等文件)是 Web程序直接提供给客户端的直接加载的文件。 较比于程序动态交互的代码而言,其实原理都一样(走Http协议),

ASP.NET Core中需要进行一些配置才能提供这些文件。

二、wwwroot

  静态文件存储在项目的 Web 程序的 {ContentRoot}/wwwroot目录下,但可通过 UseWebRoot 方法更改路径 。 

Web 应用程序项目的 wwwroot 文件夹中默认有多个文件夹 :

  • wwwroot
    • css
    • images
    • js

用于访问 images 子文件夹中的文件的 URI 格式为 http://<server_address>/images/<image_file_name> 。 例如, http://localhost:1189/images/banner.png

  通过以下代码开启静态文件访问功能(设置 {ContentRoot}/wwwroot为默认的静态文件工作目录)

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

三、设置指定目录为静态文件工作目录

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(); //   wwwroot 目录

    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), "the_path_to_yours")),
        RequestPath = "/GiveAName"
    });
}

  注意访问自定义的静态文件路径发生变化:http://localhost:1189/GiveAName/images/banner.png

四、给静态文件添加客户端缓存

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    var cachePeriod = env.Production() ? "60000" : "600";
    app.UseStaticFiles(new StaticFileOptions
    {
        OnPrepareResponse = ctx =>
        {
            // 记得下面的引用:
            // using Microsoft.AspNetCore.Http;
            ctx.Context.Response.Headers.Append("Cache-Control", $"public, max-age={cachePeriod}");
        }
    });
}

  如上,在生产环境中,我们给静态文件添加了60000(ms)的缓存,即:在一分钟内,客户端都会从浏览器本地拿文件,注意此手法,直接更新静态文件一时间是拿不到最新文件的.

 

 

五、利用PhysicalFile方法让静态文件的访问可以进行鉴权

  静态文件中间件允许浏览器端访问由静态文件中间件提供的所有静态文件(包括 wwwroot 下的文件),我们设想实际的一个应用场景,我们上传了一个文件到指定目录,而这个文件只能当事人自己可以进行访问,那么如何进行权限验证呢?

[Authorize]//身份验证
public IActionResult UsersOwnPictrue()
{
    var file = Path.Combine(Directory.GetCurrentDirectory(), 
                            "StaticFilesPath", "images", "my.svg");
    return PhysicalFile(file, "image/svg+xml");//返回静态文件
}

六、前后端分离开发中的使用

  前后端开发分离的开发模式中,前端自己负责前端的一切交互工作,不仅如此还会在后端工作没有启动前自己构造数据,ASP.NET Core静态文件中间件,正好可和此开发

模式进行衔接,此处省略一万字,有一点大家比较关心的问题:如何设置项目起始页,如何设置前端项目中的默认页

public void Configure(IApplicationBuilder app)
{
    app.UseDefaultFiles();//必须在 UseStaticFiles 前调用 UseDefaultFiles。 UseDefaultFiles 实际上用于重写 URL,不提供文件。
    app.UseStaticFiles(); //这两步
}
使用 UseDefaultFiles 会使用以下这些文件作为整个项目的默认起始页:
default.htm
default.html
index.htm
index.html
public void Configure(IApplicationBuilder app)
{
    // 使用其他文件作为默认静态页面文件
    DefaultFilesOptions options = new DefaultFilesOptions();
    options.DefaultFileNames.Clear();
    options.DefaultFileNames.Add("其他wwwroot下的.html");
    app.UseDefaultFiles(options);
    app.UseStaticFiles();
}

 

app.UseFileServer();//可将上面两步何为一步

 

七、关于UseFileServer

  UseFileServer 整合了 UseStaticFiles、UseDefaultFiles 和 UseDirectoryBrowser(可选,如果启用需要services.AddDirectoryBrowser())的功能,

public void Configure(IApplicationBuilder app)
{
   
    app.UseFileServer(new FileServerOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), "文件夹")),
        RequestPath = "/请求名",
        EnableDirectoryBrowsing = true
    });
}
请求连接 对应路径
http://<server_address>/请求名/images/file1.png 文件夹/images/file1.png
http://<server_address>/请求名/ 文件夹/default.html

八、开启目录浏览功能

  此功能通常不要开启,因为比较危险,通过目录浏览,Web 应用的用户可查看目录列表和指定目录中的文件。 出于安全考虑,调用 Startup.Configure 中的 UseDirectoryBrowser 方法来启用目录浏览:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDirectoryBrowser();
}
 app.UseDirectoryBrowser(new DirectoryBrowserOptions //开启对wwwroot/images的文件进行浏览的功能
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
        RequestPath = "/MyImages"
    });

九、指定指定文件类型的MIME类型

public void Configure(IApplicationBuilder app)
{

    var provider = new FileExtensionContentTypeProvider();

    provider.Mappings[".rtf"] = "application/x-msdownload";
    // 移除指定文件的解析
    provider.Mappings.Remove(".mp4");
    ......
}
public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(new StaticFileOptions
    {
       //未知类型的ContentType
        ServeUnknownFileTypes = true,
        DefaultContentType = "bala/your type"
    });
}

 

posted @ 2020-02-10 20:45  [秦时明月]  阅读(1561)  评论(4编辑  收藏  举报