《ASP.NET Core 高性能系列》静态文件中间件
<h4>一、概述</h4><p> 静态文件(如 HTML、CSS、图片和 JavaScript等文件)是 Web程序直接提供给客户端的直接加载的文件。 较比于程序动态交互的代码而言,其实原理都一样(走Http协议),</p>
<p>ASP.NET Core中需要进行一些配置才能提供这些文件。</p>
<h4>二、wwwroot</h4>
<p> 静态文件存储在项目的 Web 程序的 {ContentRoot}/wwwroot目录下,但可通过 UseWebRoot 方法更改路径 。 </p>
<p><span data-ttu-id="e2e4b-116">Web 应用程序项目的 wwwroot 文件夹中默认有多个文件夹 :</span></p>
<ul>
<li><span data-ttu-id="e2e4b-117"><span data-ttu-id="e2e4b-117">wwwroot</span></span>
<ul>
<li><span data-ttu-id="e2e4b-118">css</span></li>
<li><span data-ttu-id="e2e4b-119">images</span></li>
<li><span data-ttu-id="e2e4b-120">js</span></li>
</ul>
</li>
</ul>
<p><span data-ttu-id="e2e4b-121">用于访问 images 子文件夹中的文件的 URI 格式为 http://<server_address>/images/<image_file_name> 。 <span data-ttu-id="e2e4b-122">例如, <em>http://localhost:1189/images/banner.png</em>。</span></span></p>
<p><span data-ttu-id="e2e4b-121"><span data-ttu-id="e2e4b-122"> 通过以下代码开启静态文件访问功能(设置 {ContentRoot}/wwwroot为默认的静态文件工作目录)</span></span></p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles();
}
</pre>
</div>
<h4>三、设置指定目录为静态文件工作目录</h4>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Configure(IApplicationBuilder app)
{
app.UseStaticFiles(); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> wwwroot 目录</span>
<span style="color: rgba(0, 0, 0, 1)">
app.UseStaticFiles(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> StaticFileOptions
{
FileProvider </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">the_path_to_yours</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)),
RequestPath </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/GiveAName</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
});
}</span></pre>
</div>
<p> 注意访问自定义的静态文件路径发生变化:<em>http://localhost:1189/<span style="color: rgba(255, 0, 0, 1)">GiveAName</span>/images/banner.png</em></p>
<h4>四、给静态文件添加客户端缓存</h4>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Configure(IApplicationBuilder app, IHostingEnvironment env)
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> cachePeriod = env.Production() ? <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">60000</span><span style="color: rgba(128, 0, 0, 1)">"</span> : <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">600</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
app.UseStaticFiles(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> StaticFileOptions
{
OnPrepareResponse </span>= ctx =><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 记得下面的引用:
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> using Microsoft.AspNetCore.Http;</span>
ctx.Context.Response.Headers.Append(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Cache-Control</span><span style="color: rgba(128, 0, 0, 1)">"</span>, $<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">public, max-age={cachePeriod}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
}
});
}</span></pre>
</div>
<p> 如上,在生产环境中,我们给静态文件添加了60000(ms)的缓存,即:在一分钟内,客户端都会从浏览器本地拿文件,注意此手法,直接更新静态文件一时间是拿不到最新文件的.</p>
<p><em><img src="https://img2018.cnblogs.com/i-beta/83201/202002/83201-20200209211244851-767714100.png" alt=""></em></p>
<p> </p>
<p> </p>
<h4>五、利用PhysicalFile方法让静态文件的访问可以进行鉴权</h4>
<p> 静态文件中间件允许浏览器端访问由静态文件中间件提供的所有静态文件(包括 wwwroot 下的文件),我们设想实际的一个应用场景,我们上传了一个文件到指定目录,而这个文件只能当事人自己可以进行访问,那么如何进行权限验证呢?</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">身份验证</span>
<span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> IActionResult UsersOwnPictrue()
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> file =<span style="color: rgba(0, 0, 0, 1)"> Path.Combine(Directory.GetCurrentDirectory(),
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">StaticFilesPath</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">images</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">my.svg</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> PhysicalFile(file, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">image/svg+xml</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);//返回静态文件
}</span></pre>
</div>
<h4>六、前后端分离开发中的使用</h4>
<p> 前后端开发分离的开发模式中,前端自己负责前端的一切交互工作,不仅如此还会在后端工作没有启动前自己构造数据,ASP.NET Core静态文件中间件,正好可和此开发</p>
<p>模式进行衔接,此处省略一万字,有一点大家比较关心的问题:如何设置项目起始页,如何设置前端项目中的默认页</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Configure(IApplicationBuilder app)
{
<span style="color: rgba(0, 0, 255, 1)"> app.UseDefaultFiles();//<span data-ttu-id="e2e4b-174">必须在 <code>UseStaticFiles</code> 前调用 <code>UseDefaultFiles</code>。 <span data-ttu-id="e2e4b-175"><code>UseDefaultFiles</code> 实际上用于重写 URL,不提供文件。</span></span>
app.UseStaticFiles(); //这两步</span>
}</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">使用 UseDefaultFiles 会使用以下这些文件作为整个项目的默认起始页:
</span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)">.htm
</span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)">.html
index.htm
index.html</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Configure(IApplicationBuilder app)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 使用其他文件作为默认静态页面文件</span>
DefaultFilesOptions options = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">其他wwwroot下的.html</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
app.UseDefaultFiles(options);
app.UseStaticFiles();
}</span></pre>
</div>
<p> </p>
<div class="cnblogs_code">
<pre>app.UseFileServer();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">可将上面两步何为一步</span></pre>
</div>
<p> </p>
<h4>七、关于UseFileServer</h4>
<p> UseFileServer 整合了 UseStaticFiles、UseDefaultFiles 和 UseDirectoryBrowser(可选,如果启用需要services.AddDirectoryBrowser())的功能,</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Configure(IApplicationBuilder app)
{
app.UseFileServer(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> FileServerOptions
{
FileProvider </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">文件夹</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)),
RequestPath </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/请求名</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
EnableDirectoryBrowsing </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
});
}</span></pre>
</div>
<table style="height: 130px; width: 560px" border="1">
<tbody>
<tr>
<td>请求连接</td>
<td>对应路径</td>
</tr>
<tr>
<td>http://<server_address>/请求名/images/file1.png</td>
<td style="text-align: left">文件夹/images/file1.png</td>
</tr>
<tr>
<td>http://<server_address>/请求名/</td>
<td>文件夹/default.html</td>
</tr>
</tbody>
</table>
<h4>八、开启目录浏览功能</h4>
<p> 此功能通常不要开启,因为比较危险,<span data-ttu-id="e2e4b-161">通过目录浏览,Web 应用的用户可查看目录列表和指定目录中的文件。 <span data-ttu-id="e2e4b-162">出于安全考虑,<span data-ttu-id="e2e4b-163">调用 <code>Startup.Configure</code> 中的 UseDirectoryBrowser 方法来启用目录浏览:</span></span></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> ConfigureServices(IServiceCollection services)
{
services.AddDirectoryBrowser();
}</span></pre>
</div>
<div class="cnblogs_code">
<pre> app.UseDirectoryBrowser(<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> DirectoryBrowserOptions //开启对wwwroot/images的文件进行浏览的功能
{
FileProvider </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">wwwroot</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">images</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)),
RequestPath </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/MyImages</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
});</span></pre>
</div>
<h4>九、指定指定文件类型的MIME类型</h4>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Configure(IApplicationBuilder app)
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> provider = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> FileExtensionContentTypeProvider();
provider.Mappings[</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">.rtf</span><span style="color: rgba(128, 0, 0, 1)">"</span>] = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">application/x-msdownload</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 移除指定文件的解析</span>
provider.Mappings.Remove(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">.mp4</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
......
}</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Configure(IApplicationBuilder app)
{
app.UseStaticFiles(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> StaticFileOptions
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">未知类型的ContentType</span>
ServeUnknownFileTypes = <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
DefaultContentType </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">bala/your type</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
});
}</span></pre>
</div>
<p> </p>
</div>
<div id="MySignature" role="contentinfo">
<br><br><br>
<h4>少侠,我看你气度不凡天赋异禀,骨骼精奇,这么帅,来了就帮推荐一把吧</h4><br><br><br>
<div class="moonnote">我的最近更新</div>
最新发布文章、框架、咨询等,来看看吧<br><br>
来源:https://www.cnblogs.com/thinkingmore/p/12288903.html
頁:
[1]