• Asp .Net core 2 学习笔记(3) —— 静态文件


    这个系列的初衷是便于自己总结与回顾,把笔记本上面的东西转移到这里,态度不由得谨慎许多,下面是我参考的资源:

     ASP.NET Core 中文文档目录

    官方文档

    记在这里的东西我会不断的完善丰满,对于文章里面一些局限于我自己知识积累的观点,希望没有跳走坚持看完的朋友,能够予以指正和鼓励.

    系列目录

    (1)Starup

    (2)中间件

    (3)静态文件

    静态文件

    在上节中间件一节我们提到:静态文件中间件可以处理对静态文件的请求,并让管道的其余部分短路,从而起到终端中间件的作用

    这一节我们对静态文件做一个更深入的了解. 以一个新建的.Net core Web项目(有视图模型控制器的模版)为例

    提供静态文件

    应用的Web主机必须识别内容根目录。

    项目Program.cs内容如下, 采用WebHost.CreateDefaultBuilder方法可将内容根目录设置为当前目录:

     1     public class Program
     2     {
     3         public static void Main(string[] args)
     4         {
     5             CreateWebHostBuilder(args).Build().Run();
     6         }
     7 
     8         public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
     9             WebHost.CreateDefaultBuilder(args)
    10                 .UseStartup<Startup>();
    11     }

    提供 Web 根目录内的文件

    静态文件存储在项目的Web根目录中。 默认目录是 <content_root>/wwwroot,所以在项目wwwroot下面我们看到了如下结构

     但是仅仅将内容根目录设置为当前目录还不行,我们还得在Starup启动类的Configure方法下添加静态文件中间件组件才行,

    无参数的UseStaticFiles方法重载将Web根目录中的文件标记为可用
    1     public void Configure(IApplicationBuilder app)
    2     {
    3       app.UseStaticFiles();
    4 }

    这样wwwroot目录下的组员文件才能被访问,例如引用css文件

    <link rel="stylesheet" href="~/css/site.css" />

     假设我们把上述的UseStaticFiles方法注释掉,我们启动项目后就会发现页面的样式完全发生变化,那是因为在wwwroot里面的样式文件被禁止访问了

    更改默认目录

    上面说到静态文件默认的目录是 <content_root>/wwwroot,如果想换成别的命名,例如:<content_root>/staticroot,该如何操作呢?

    我们可以通过WebHost.CreateDefaultBuilder方法,使用UseWebRoot更改默认目录,代码如下
     
     1     public class Program
     2     {
     3         public static void Main(string[] args)
     4         {
     5             CreateWebHostBuilder(args).Build().Run();
     6         }
     7 
     8         public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
     9             WebHost.CreateDefaultBuilder(args)
    10                 //当前目录下的staticroot文件夹
    11                 .UseWebRoot(Path.Combine(Directory.GetCurrentDirectory(), "staticroot"))
    12                 .UseStartup<Startup>();
    13     }

     这样这样静态文件的默认目录由 <content_root>/wwwroot变为<content_root>/staticroot,如果不将项目的静态资源转移到<content_root>/staticroot下,那么项目中的静态资源将无法被访问

    提供 Web 根目录外的文件

    如果我们使用默认设置,那么静态文件的访问都是跳到了wwwroot下,这个时候问题就出现了,,假设有如下的目录结构

     

    怎么设置能够使得同级目录也能够被访问,比如既能够访问<content_root>/wwwroot/img/header.jpg,又能够访问<content_root>/MyStaticFiles/images/header.jpg

    这时候就需要有参数的UseStaticFiles方法,通过StaticFileOptions对象来解决

     1       public void Configure(IApplicationBuilder app)
     2         {
     3             // For the wwwroot folder
     4             app.UseStaticFiles();
     5             // For the /MyStaticFiles url
     6             app.UseStaticFiles(new StaticFileOptions
     7             {
     8                 FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
     9                 RequestPath = "/MyStaticFiles"
    10             });
    11         }

    这样设置,2个同级目录就都可以访问了

    设置 HTTP 响应标头

    在静态文件中间件组件中,上述的StaticFileOptions 对象还可用于设置 HTTP 响应标头。

    举例而言,以下代码除了配置从 Web 根目录提供静态文件外,还设置 Cache-Control 标头:

     1         public void Configure(IApplicationBuilder app, IHostingEnvironment env)
     2         {
     3             var cachePeriod = env.IsDevelopment() ? "600" : "604800";
     4             app.UseStaticFiles(new StaticFileOptions
     5             {
     6                 OnPrepareResponse = ctx =>
     7                 {
     8                     // Requires the following import:
     9                     // using Microsoft.AspNetCore.Http;
    10                     ctx.Context.Response.Headers.Append("Cache-Control", $"public, max-age={cachePeriod}");
    11                 }
    12             });
    13         }
    效果:在开发环境中可公开缓存这些文件 10 分钟(600 秒):

    静态文件授权

    静态文件模块并不提供授权检查。在上面设置wwwroot可以访问后,  wwwroot 下的所有文件都是公开的

    所以为了给文件提供授权,你需要有如下的操作:

        1将文件保存在 wwwroot 和静态文件中间件可以访问到的任何目录之外
        2通过一个控制器的 Action 来访问它们,通过授权后返回 FileResult

    1         [Authorize]
    2         public IActionResult BannerImage()
    3         {
    4             var file = Path.Combine(Directory.GetCurrentDirectory(),
    5             "MyStaticFiles", "images", "header.jpg");
    6              return PhysicalFile(file, "image/jpg+xml");
    7         }

    这样,只有通过了身份认证才能够得到文件信息

    启用目录浏览

    目录浏览允许网站用户看到指定目录下的目录和文件列表。

    但是基于安全考虑,默认情况下是禁用目录访问功能的。

    在 Startup.Configure 中调用 UseDirectoryBrowser 扩展方法可以开启网络应用目录浏览:

    1         public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    2         {
    3             app.UseDirectoryBrowser(new DirectoryBrowserOptions
    4             {
    5                 FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")),
    6                 RequestPath = "/Browser"
    7             });
    8         }

    访问 <content_root>/Browser后效果如下

    官方文档说明:还需要调用 Startup.ConfigureServices 中的AddDirectoryBrowser 方法,如下

    1         public void ConfigureServices(IServiceCollection services)
    2         {
    3             services.AddDirectoryBrowser();
    4         }

    但是我测试的时候没有注册这个服务,仍然可以启用目录,大家在用到或者测试的时候可用留意一下

    默认文档服务

    设置默认首页能给你的站点的每个访问者提供一个起始页。使站点能提供默认页,避免用户输入完整 URI.

    输入以下代码

    1         public void Configure(IApplicationBuilder app)
    2            {
    3                   app.UseDefaultFiles();
    4                   app.UseStaticFiles();
    5            }
     
    Warnning
    要提供默认文件,必须在 UseStaticFiles 前调用 UseDefaultFiles 。 UseDefaultFiles 实际上用于重写 URL,不提
    供文件。 通过 UseStaticFiles 启用静态文件中间件来提供文件。
     

    项目启动后,会在指定的目录(未设置则在wwwroot下)按如下顺序搜索文件,来作为网站的起始页

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

    对于所用示例mvc项目来说,项目启动后,因为路由的原故,路径自动跳转到/home/index下,如果设置了提供默认文档,那么会按照下面的情况(一般而言静态文件中间件会放在前面,具体情况还是以中间件添加顺序为准)

    路径 实际访问
    http://localhost:xxx wwwroot下default.html
    http://localhost:xxx/home home控制器index方法
    http://localhost:xxx/home/Idex home控制器index方法
     
     
    起始页默认是按上述的4个htm页面顺序来查找的,我们也可以更改为查找特定路径,代码如下
    1         public void Configure(IApplicationBuilder app)
    2         {
    3             // Serve my app-specific default file, if present.
    4             DefaultFilesOptions options = new DefaultFilesOptions();
    5             options.DefaultFileNames.Clear();
    6             options.DefaultFileNames.Add("index.html");
    7             app.UseDefaultFiles(options);
    8             app.UseStaticFiles();
    9         }

    这样就变成了直接查找index.html,但是如果未找到index.html,那么会直接404找不到页面,而不会存在原来的查找顺序

    UseFileServer

    UseFileServer 结合了上述UseStaticFiles 、 UseDefaultFiles 和 UseDirectoryBrowser 的功能。 
    以下代码启用静态文件、默认文件和及 MyStaticFiles 的目录浏览: 
     
    1         public void Configure(IApplicationBuilder app)
    2         {
    3             app.UseFileServer(new FileServerOptions
    4             {
    5                 FileProvider = new PhysicalFileProvider( Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
    6                 RequestPath = "/MyStaticFIles",
    7                 EnableDirectoryBrowsing = true
    8             });
    9         }

    访问<content_root>/MyStaticFIles/会有下面2种情况:

    1/MyStaticFIles文件夹下没有default.htm,default.html,index.htm,index.html

    2/MyStaticFIles文件夹下存在default.htm,default.html,index.htm,index.html一个或多个作为默认文档

    非标准的内容类型

    ASP.NET 静态文件中间件能够支持超过 400 种已知文件内容类型。

    如果用户请求一个未知的文件类型,静态文件中间件将返回 HTTP 404(未找到)响应。

    如果启用目录浏览,该文件的链接将会被显示,但 URI 会返回一个 HTTP 404 错误。

    1         public void Configure(IApplicationBuilder app)
    2         {
    3             app.UseStaticFiles(new StaticFileOptions
    4             {
    5                 ServeUnknownFileTypes = true,
    6                 DefaultContentType = "image/png"
    7             });
    8         }

    根据上面的代码,未知内容类型的文件请求将返回一张图片,而不会返回一个未找到的错误。

    Warnning

    • 代码文件(包括 C# 和 Razor)应该放在应用程序项目的 wwwroo(默认为wwwroot)之外的地方。这将确保您创建的应用程序能明确隔离客户端侧和服务器侧源代码,此举能防止服务器侧的代码被泄露。同时,不要在生产环境开启目录浏览

     (终)

    文档信息


    感谢您的阅读,如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮。本文欢迎各位转载,但是转载文章之后必须在文章页面中给出作者和原文连接
  • 相关阅读:
    git pull --rebase 做了什么? 以及 Cannot rebase: You have unstaged changes 解决办法
    Android pix转换为sp
    职业四象限,分分钟定位你的方向
    我的微信公众号开通了!
    Android PermissionChecker 权限全面详细分析和解决方案
    Android沉浸式(侵入式)标题栏(状态栏)Status(三)
    Android沉浸式(侵入式)标题栏(状态栏)Status(二)
    Android沉浸式(侵入式)标题栏(状态栏)Status(一)
    为毛老抱怨工资低又不离职
    面试题:return和finally执行
  • 原文地址:https://www.cnblogs.com/banluduxing/p/10753608.html
Copyright © 2020-2023  润新知