这篇讲解asp.net core中的静态文件(大致翻译于官网)。

静态文件,例如HTML,CSS, images和JavaScript. 要想直接被客户端访问,需要做一些配置。

一.Serve static files(提供静态文件服务)

静态文件存储在项目的web root 目录下。默认的目录是<content_root>/wwwroot,但可以通过UseWebRoot方法来改变默认目录。

更多可以查看: See Content root and Web root for more information.

应用的web host 必须知道内容根目录。

WebHost.CreateDefaultBuilder方法设置内容根目录到当前目录中:

public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
} public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}

静态文件可以通过一个相对web root的路径来访问。

例如,web application 项目模板在wwwroot文件夹下包含几个文件夹:

  • wwwroot
    • css
    • images
    • js

到images子目录中的文件的URI格式为:http://<server_address>/images/<image_file_name> 。 例如,

http://localhost:9189/images/banner3.svg.

如果是.NET Framework, 添加 Microsoft.AspNetCore.StaticFiles包到项目中。如果是.NET Core, Microsoft.AspNetCore.App包含这个包。

配置中间件来允许提供静态文件的服务。

1.Serve files inside of web root(在web root中提供files服务)

在Startup.Configure中调用UseStaticFiles方法:

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

这个无参的UseStaticFiles方法标志着web root中的文件可以提供服务。下面的标签引用 wwwroot/images/banner1.svg:

<img src="~/images/banner1.svg" alt="ASP.NET" class="img-responsive" />

在上面的代码中,~/ 指向webroot,更多信息:Web root.

像上面的代码,要使用web root下的文件,需要直接指向到web root下的具体的文件。

2.Serve files outside of web root(在web root外提供文件服务)

考虑下面的目录层级,将在web root外面的MyStaticFiles提供文件服务。

通过配置静态文件中间件(the Static File Middleware),使请求可以取得banner1.svg文件:

public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles(); // For the wwwroot folder app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
RequestPath = "/StaticFiles"
});
}

在上面的代码中,MyStaticFiles目录通过StaticFiles 的URI被暴露。

一个 到http://<server_address>/StaticFiles/images/banner1.svg 的请求,可以得到banner1.svg文件。

下面的标记引用MyStaticFiles/images/banner1.svg文件:

<img src="~/StaticFiles/images/banner1.svg" alt="ASP.NET" class="img-responsive" />

3.Set HTTP response headers(设置HTTP响应头)

StaticFileOptions 对象可以被用来设置HTTP response headers(HTTP 响应头)。

另外配置静态文件服务于web root, 下面的代码设置了Cache-Control 头:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var cachePeriod = env.IsDevelopment() ? "" : "";
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
// Requires the following import:
// using Microsoft.AspNetCore.Http;
ctx.Context.Response.Headers.Append("Cache-Control", $"public, max-age={cachePeriod}");
}
});
}

HeaderDictionaryExtensions.Append方法存在于Microsoft.AspNetCore.Http包中。

这个文件在开发环境可以缓存10分钟(600秒)。

二.Static file authorization(静态文件授权)

静态文件中间件不会提供授权检查。任何被它提供的文件服务,包括在wwwroot下的,都是公开可以访问的。

要基于授权提供文件服务:

  • 把它们存储在wwwroot外面 和 对于静态文件中间件可以到达的任意目录
  • 通过认证的action方法提供它们。返回一个FileResult对象:
[Authorize]
public IActionResult BannerImage()
{
var file = Path.Combine(Directory.GetCurrentDirectory(),
"MyStaticFiles", "images", "banner1.svg"); return PhysicalFile(file, "image/svg+xml");
}

三.Enable directory browsing(允许目录浏览)

目录浏览允许你的web应用上的用户看见一个目录列表,和指定目录里的文件。

目录浏览因为安全原因默认是被禁用的。可以在Startup.Configure方法中调用UseDirectoryBrowser方法来允许目录浏览:

public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles(); // For the wwwroot folder app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
RequestPath = "/MyImages"
}); app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
RequestPath = "/MyImages"
});
}

通过在Startup.ConfigureServices中调用AddDirectoryBrowser方法来添加必要的服务:

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

上面的代码允许 wwwroot/images目录下的目录浏览,通过 http://<server_address>/MyImages

使用这个链接来到达每个文件和目录:

允许目录浏览的一些安全风险,可以看 Considerations

注意下面示例中的两个UseStaticFiles的调用。

第一个调用允许wwwroot文件夹提供静态文件。

第二个调用允许wwwroot/images文件夹使用目录浏览,通过http://<server_address>/MyImages :

public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles(); // For the wwwroot folder app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
RequestPath = "/MyImages"
}); app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
RequestPath = "/MyImages"
});
}

四.Serve a default document(提供一个默认文档)

当访问你的网站时,设置一个默认的home page页面提供给浏览者一个合乎逻辑的起始页(默认页)(starting point)。

要提供一个默认的不需要用户详细修饰的URI的页面,需要在Startup.Configure中调用UseDefaultFiles方法:

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

重点:UseDefaultFiles 必须在UseStaticFiles之前被调用来提供默认文件。UseDefaultFiles是一个URL重写器,它不会真正提供文件服务。允许Static File Middleware通过UseStaticFiles来提供服务。

使用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(使用文件服务器)

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

下面的代码允许提供静态文件服务和默认文件。目录浏览没被允许。

app.UseFileServer();

下面的代码是建立在无参重载上的,允许目录浏览:

app.UseFileServer(enableDirectoryBrowsing: true);

考虑下面的目录层级:

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

public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles(); // For the wwwroot folder app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
RequestPath = "/StaticFiles",
EnableDirectoryBrowsing = true
});
}

当EnableDirectoryBrowsing属性值是true时,AddDirectoryBrowser必须被调用:

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

使用文件层级和之前的代码,URLs解析如下:

如果在MyStaticFiles目录中,没有默认名称的文件存在,http://<server_address>/StaticFiles

返回目录列表中被点击的链接:

六.FileExtensionContentTypeProvider

FileExtensionContentTypeProvider类包含一个映射属性,这个映射属性提供一个file extensions 到MIME content types 的映射。下面的代码中,几个文件扩展(file extensions)被注册为已知的MIME types。 .rtf extension被替换了,并且 .mp4 被移除了。

public void Configure(IApplicationBuilder app)
{
// 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(), "wwwroot", "images")),
RequestPath = "/MyImages",
ContentTypeProvider = provider
}); app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
RequestPath = "/MyImages"
});
}

更多:MIME content types.

七.Non-standard content types(非标准类型)

Static File Middleware 理解几乎400个已知的文件类型(file content types).

如果用户请求一个未知的文件类型,Static File Middleware 会传递这个请求到管道上的下一个中间件。

如果没有中间件可以处理这个请求,一个404 Not Found 响应会被返回。

如果目录浏览被允许,在目录列表中,一个到这个文件的链接会被展示。

下面的代码允许提供未知的类型,并且渲染未知的文件为一个图片:

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

使用上面的代码,一个对未知文件类型的请求会作为一个图片返回。

警告:允许ServeUnknownFileTypes是有安全风险的。它默认是被禁用的,并且这种用法不推荐使用。FileExtensionContentTypeProvider提供一个更安全的可选的方式来提供带有non-standard extensions扩展的文件。

Considerations(考虑)

  • 使用UseDirectoryBrowser和UseStaticFiles来暴露内容的URLs是适合于大小写敏感并且在文件系统下有字符限制。例如,Windows是大小写敏感的,macOS和Linux不是。
  • ASP.NET Core 应用部署在IIS上,使用ASP.NET Core Module 来发送所有的请求到应用,包括静态文件请求。IIS静态文件处理器(IIS static file handler)没有使用。它没有机会处理请求在它们被这个模块处理之前。
  • 在IIS Manager中移除IIS static file handler的步骤,在服务器或者网站层次:
    1. 导航到Modules功能
    2. 选择列表中的StaticFileModule
    3. 点击删除

警告:如果IIS文件处理器被允许并且ASP.NET Core Module没有被正确配置,静态文件会提供服务。这会发生,例如,如果web.config文件没有被部署。

  • 存放代码文件(包括.cs和.cshtml)在项目的web root的外面。应用的客户端内容和服务端代码在逻辑上应该被分开建立,(app’s client-side content and server-based code).这可以预防服务端代码被泄露。

地址:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-2.2

asp.net core 系列之静态文件的更多相关文章

  1. ASP.NET Core应用针对静态文件请求的处理[1]: 以Web的形式发布静态文件

    虽然ASP.NET Core是一款"动态"的Web服务端框架,但是在很多情况下都需要处理针对静态文件的请求,最为常见的就是这对JavaScript脚本文件.CSS样式文件和图片文件 ...

  2. ASP.NET Core应用针对静态文件请求的处理[5]: DefaultFilesMiddleware中间件如何显示默认页面

    DefaultFilesMiddleware中间件的目的在于将目标目录下的默认文件作为响应内容.我们知道,如果直接请求的就是这个默认文件,那么前面介绍的StaticFileMiddleware中间件会 ...

  3. ASP.NET Core应用针对静态文件请求的处理[4]: DirectoryBrowserMiddleware中间件如何呈现目录结构

    和StaticFileMiddleware中间件一样,DirectoryBrowserMiddleware中间本质上还是定义了一个请求地址与某个物理目录之间的映射关系,而目标目录体现为一个FilePr ...

  4. ASP.NET Core应用针对静态文件请求的处理[3]: StaticFileMiddleware中间件如何处理针对文件请求

    我们通过<以Web的形式发布静态文件>和<条件请求与区间请求>中的实例演示,以及上面针对条件请求和区间请求的介绍,从提供的功能和特性的角度对这个名为StaticFileMidd ...

  5. ASP.NET Core应用针对静态文件请求的处理[2]: 条件请求与区间请求

    通过调用ApplicationBuilder的扩展方法UseStaticFiles注册的StaticFileMiddleware中间件帮助我们处理针对文件的请求.对于StaticFileMiddlew ...

  6. ASP.NET Core 1.1 静态文件、路由、自定义中间件、身份验证简介

    概述 之前写过一篇关于<ASP.NET Core 1.0 静态文件.路由.自定义中间件.身份验证简介>的文章,主要介绍了ASP.NET Core中StaticFile.Middleware ...

  7. (5)ASP.NET Core 中的静态文件

    1.前言 当我们创建Core项目的时候,Web根目录下会有个wwwroot文件目录,wwwroot文件目录里面默认有HTML.CSS.IMG.JavaScript等文件,而这些文件都是Core提供给客 ...

  8. Asp.Net Core 中的静态文件

    Asp.Net Core 中的静态文件 在这节中我们将讨论如何使 ASP.NET Core 应用程序,支持静态文件,如 HTML,图像,CSS 和 JavaScript 文件. 静态文件 默认情况下, ...

  9. ASP.NET Core 1.0 静态文件、路由、自定义中间件、身份验证简介

    概述 ASP.NET Core 1.0是ASP.NET的一个重要的重新设计. 例如,在ASP.NET Core中,使用Middleware编写请求管道. ASP.NET Core中间件对HttpCon ...

随机推荐

  1. 一个拼图工具TImageBox的制作思路

    http://www.cnblogs.com/del/archive/2010/04/24/1719631.html

  2. spark streaming 接收kafka消息之二 -- 运行在driver端的receiver

    先从源码来深入理解一下 DirectKafkaInputDStream 的将 kafka 作为输入流时,如何确保 exactly-once 语义. val stream: InputDStream[( ...

  3. Spring如何解决循环引用

    概念 什么是循环引用? 故名思义,多个对象形成环路. 有哪几种循环引用? 在Spring中存在如下几种循环引用,一一举例分析一下 注入循环引用(Set注入 注解注入) package c.q.m; i ...

  4. Spark学习之路(十三)—— Spark Streaming 与流处理

    一.流处理 1.1 静态数据处理 在流处理之前,数据通常存储在数据库,文件系统或其他形式的存储系统中.应用程序根据需要查询数据或计算数据.这就是传统的静态数据处理架构.Hadoop采用HDFS进行数据 ...

  5. Hive 学习之路(五)—— Hive 分区表和分桶表

    一.分区表 1.1 概念 Hive中的表对应为HDFS上的指定目录,在查询数据时候,默认会对全表进行扫描,这样时间和性能的消耗都非常大. 分区为HDFS上表目录的子目录,数据按照分区存储在子目录中.如 ...

  6. Kafka 学习之路(四)—— Kafka消费者详解

    一.消费者和消费者群组 在Kafka中,消费者通常是消费者群组的一部分,多个消费者群组共同读取同一个主题时,彼此之间互不影响.Kafka之所以要引入消费者群组这个概念是因为Kafka消费者经常会做一些 ...

  7. spring 5.x 系列第12篇 —— 整合memcached (代码配置方式)

    文章目录 一.说明 1.1 XMemcached客户端说明 1.2 项目结构说明 1.3 依赖说明 二.spring 整合 memcached 2.1 单机配置 2.2 集群配置 2.3 存储基本类型 ...

  8. Java NIO 学习笔记(七)----NIO/IO 的对比和总结

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  9. memecached存放session数据

    memcached存放session 1.session数据需要频繁调用. 2.session数据不需要永久性的保存在服务端. 3.在集群中,可以将session存放在memcached中或者是在数据 ...

  10. PATA 1071 Speech Patterns.

    #include <bits/stdc++.h> using namespace std; bool check(char c)//检查是否为字母或数字 { if(c>='A'&am ...