zoukankan      html  css  js  c++  java
  • ASP.NET Core 2.2 基础知识(三) 静态文件

    什么是静态文件?

    HTML,CSS,JS,图片等都叫做静态文件.

    要想提供静态文件给客户端,需要注册静态文件中间件.

    我们先分别添加一个 WebAPI 项目,一个 Razor 视图项目,比较两个项目的 Startup 类的 Configure 方法: 

    WebAPI项目:

    Razor项目:

    可以看出,Razor项目多了一行代码 app.UseStaticFiles();  (下面那一行先不管)

    这行代码的作用就是注册静态文件中间件.

    UseStaticFiles() 方法的 xml 注释是这样写的 : Enables static file serving for the current request path.为当前请求路径提供静态文件服务.

    之所以 WebAPI 项目没有注册静态文件中间件,是因为 WebAPI 的定义和 Razor,MVC 不一样.

    我们再来比较一下 WebAPI 项目和 Razor 项目:

    (Pages 文件夹先不管)

    可以看出,Razor 项目多了一个叫 wwwroot 的东西.别看它图标是个球,其实它就是一个文件夹:

    那么问题来了,既然 Razor 项目提供了静态文件中间件,那这个 wwwroot 文件夹里面的文件怎么访问呢?他们的路径是什么呢?

    比如,我们现在要访问 wwwroot/css/site.css 

    当然,如果我们把 app.UseStaticFiles(); 注释掉,就404了:

    从上面的例子中,可以看出,我们访问的是路径是: https://localhost:44301/css/site.css ,而不是  https://localhost:44301/wwwroot/css/site.css

    显然,系统默认了 wwwroot 文件夹,那这个默认的路径在哪里可以看呢?

    我们在 Pages 文件下的 Index.cshtml 页面中增加如下代码:(红色标注)

    上面那行表示给 env 变量注入一个 IHostingEnvironment 类型的实例.

    页面显示如下:

    现在问题又来了,如果想访问 wwwroot 文件夹外的文件,应该怎么设置路径呢?

    我们先添加一个文件夹 images,放入两张图片:

    在 Startup 类中加入如下代码(红色标注): 

            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                ...other codes
    app.UseStaticFiles();
           //下面这个静态文件中间件的设置,只针对其设置的文件路径下的文件生效,和上面默认的静态文件路径 wwwroot 下的文件访问相互独立. app.UseStaticFiles(
    new StaticFileOptions { FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Images")),//设置文件路径(物理路径) RequestPath = new PathString(@"/files"),//设置访问路径(虚拟路径) OnPrepareResponse = context => { context.Context.Response.Headers.Append("Cache-Control", "public,max-age=600");//设置缓存 }, });        
    ...other codes }

    设置缓存的代码是顺带写的,仅仅表示有这个功能,跟设置路径没有关系.

    请求自定义文件路径:

    请求 wwwroot 文件夹下的文件:

    可以看到,响应中没有缓存设置了,这证明了两者相互独立.

    除了可以设置文件路径,访问路径,缓存外, StaticFileOptions 类还有3个属性:

    1.ContentTypeProvider  内容提供器

    它的功能,直接看代码就明白了.

                var fileProvider = new FileExtensionContentTypeProvider();
                fileProvider.Mappings.Remove(".jpg");//移除对 ".jpg" 文件的响应
                fileProvider.Mappings[".laotie"] = "image/jpeg";//添加对 ".laotie" 文件的响应析,响应格式为 "image/jpeg"
    
                //下面这个静态文件中间件的设置,只针对其设置的文件路径下的文件生效,和上面默认的静态文件路径 wwwroot 下的文件访问相互独立.
                app.UseStaticFiles(new StaticFileOptions
                {
                    FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Images")),//设置文件路径(物理路径)
                    RequestPath = new PathString(@"/files"),//设置访问路径(虚拟路径)
                    OnPrepareResponse = context =>
                    {
                        context.Context.Response.Headers.Append("Cache-Control", "public,max-age=600");//设置缓存
                    },
                    ContentTypeProvider = fileProvider,//设置文件提供器
                });

    我们再次请求 : https://localhost:44301/files/1.jpg

     请求 : https://localhost:44301/files/3.laotie

    2.ServeUnknownFileTypes

    3.DefaultContentType

    这两个属性一起说.

    ServeUnknownFileTypes 的 xml 注释是这样写的 : If the file is not a recognized content-type should it be served?Default: false. 如果文件不是被认可的类型,那么它是否应该提供(给客户端)?默认:不提供.

    那么哪些类型是认可的呢?太多了....截一小部分图:(这都是些啥类型啊,好诡异.小弟表示没见过)

    如果 ServeUnknownFileTypes 设置为 true,则表示要提供(给客户端),而且是采用 DefaultContentType 属性设置的响应类型提供.

    而 DefaultContentType 的 xml 注释是这样写的 :  

    //The default content type for a request if the ContentTypeProvider cannot determine one. 如果 ContentTypeProvider  属性设置的提供器不能选择出一个认可的类型,则采用该属性设置的响应类型.

    //None is provided by default, so the client must determine the format themselves.如果该属性没有提供响应类型(即该属性没有值,为null),则交给客户端来格式化它们.

    测试如下:

    我们将 上述代码中的 fileProvider.Mappings[".laotie"] = "image/jpeg" 注释掉,注释后的完整代码如下:

                var fileProvider = new FileExtensionContentTypeProvider();
                fileProvider.Mappings.Remove(".jpg");//移除对 ".jpg" 文件的解析
                //fileProvider.Mappings[".laotie"] = "image/jpeg";//添加对 ".laotie" 文件的解析,解析方式为 "image/jpeg"
    
                //下面这个静态文件中间件的设置,只针对其设置的文件路径下的文件生效,和上面默认的静态文件路径 wwwroot 下的文件访问相互独立.
                app.UseStaticFiles(new StaticFileOptions
                {
                    FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Images")),//设置文件路径(物理路径)
                    RequestPath = new PathString(@"/files"),//设置访问路径(虚拟路径)
                    OnPrepareResponse = context =>
                    {
                        context.Context.Response.Headers.Append("Cache-Control", "public,max-age=600");//设置缓存
                    },
                    ContentTypeProvider = fileProvider,//设置文件提供器
                });

     我们再次请求 https://localhost:44301/files/3.laotie , 结果 404,因为我们删掉了对 ".老铁" 文件类型的认可,而 ServeUnknownFileTypes  默认值又为 false

    当我们把 ServeUnknownFileTypes 属性设置为 ture :

                app.UseStaticFiles(new StaticFileOptions
                {
                    FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Images")),//设置文件路径(物理路径)
                    RequestPath = new PathString(@"/files"),//设置访问路径(虚拟路径)
                    OnPrepareResponse = context =>
                    {
                        context.Context.Response.Headers.Append("Cache-Control", "public,max-age=600");//设置缓存
                    },
                    ContentTypeProvider = fileProvider,//设置文件提供器
                    ServeUnknownFileTypes = true,
                });

    再次请求 https://localhost:44301/files/3.laotie ,则正常显示出了内容(图就不上了)

    我以为:如果设置 DefaultContentType  = "text/plain" ,那么 3.laotie 应该不能正常访问,但实际上还是可以访问.有点不明白.希望高手解答一下.

    跟文件访问相关的中间件,除了上面提到的静态文件中间件外,还有两个:

    1.默认文件中间件 app.UseDefaultFiles()

    默认文件中间件的默认文件有4种:default.htm,default.html,index.htm,index.html

    当然,我们也可以自定义.

    下面的示例给出了默认中间件的相关功能.

                //提供默认文件
                DefaultFilesOptions options = new DefaultFilesOptions
                {
                    FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Default")),
                };
                options.DefaultFileNames.Add("mydefault.html");//添加自定义的默认文件
                app.UseDefaultFiles(options);
    
                app.UseStaticFiles();
    
                //使用静态文件中间件 
                app.UseStaticFiles(new StaticFileOptions
                {
                    FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Default"))
                });

    有两点要特别注意:

    1)必须在 UseStaticFiles 前调用 UseDefaultFiles .UseDefaultFiles 实际上用于重写 URL,不提供文件,真正提供文件的依然是 UseStaticFiles .

    2)两个中间件的路径必须设置一样.理由就是第一条.

    2.目录浏览中间件  app.UseDirectoryBrowser()

    该中间件的启用方式,设置方式和静态文件中间件类似.

    由于涉及安全考虑,微软默认没有启动该中间件.

                //启用目录浏览中间件
                app.UseDirectoryBrowser();
                app.UseDirectoryBrowser(new DirectoryBrowserOptions
                {
                    FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Images")),
                    RequestPath = new PathString(@"/files"),
                });

    除了上述3种文件相关的中间件外,系统提供了一个3合一的中间件:

                //同时启用默认的静态文件,默认文件,静态目录浏览中间件,false 则不启动静态目录浏览.
                app.UseFileServer(true);

    处于安全考虑,要启动目录浏览中间件,需要传入 true .

    完.

     

  • 相关阅读:
    下载安装Cygwin
    WEB中调用Nutch执行JOB抓取
    IKAnalyzer 分词
    【转】JDBC连接数据库
    单例模式的常见写法
    14 Go's Declaration Syntax go语言声明语法
    13 JSON-RPC: a tale of interfaces
    12 Release History for go go语言的版本历史
    11 The Go Memory Model go语言内置模型
    09 Command Documentation 命令文档
  • 原文地址:https://www.cnblogs.com/refuge/p/10208976.html
Copyright © 2011-2022 走看看