继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

ASP.NET Core 2.2 基础知识(三) 静态文件

慕斯709654
关注TA
已关注
手记 317
粉丝 37
获赞 183

什么是静态文件?

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 .

原文出处:https://www.cnblogs.com/refuge/p/10208976.html  

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP