WebEnh

.net7 mvc jquery bootstrap json 学习中 第一次学PHP,正在研究中。自学进行时... ... 我的博客 https://enhweb.github.io/ 不错的皮肤:darkgreentrip,iMetro_HD
  首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

细说ASP.NET Core静态文件的缓存方式

Posted on 2016-12-05 13:46  WebEnh  阅读(733)  评论(0编辑  收藏  举报
2016-11-26 张磊 dotNET跨平台

一、前言

  我们在优化Web服务的时候,对于静态的资源文件,通常都是通过客户端缓存服务器缓存CDN缓存,这三种方式来缓解客户端对于Web服务器的连接请求压力的。

  本文指在这三个方面,在ASP.NET Core中静态文件的实现过程和使用方法进行阐述。当然也可以考虑使用反向代理的方式(例如IIS或Nginx),这些不是本文讨论的内容。

  本文重点展示如何通过StaticFileMiddleware中间件,提高网站的性能。虽然这不是唯一缓存文件的方式,我们还可以通过ResponseCacheAttribute特性为ASP.NET Core Mvc的Controller和Action进行缓存的设置。

 

二、StaticFileMiddleware

  1.文件服务与默认缓存规则

  当创建一个ASP.NET Core的项目时,查看Startup.Configure方法,就会看到默认模板生成的添加StaticFileMiddleware中间件的方法。

  1. public void Configure(IApplicationBuilder app)  

  2. {

  3.    // looging and exception handler removed for clarity

  4.  

  5.    app.UseStaticFiles();

  6.  

  7.    app.UseMvc(routes =>

  8.    {

  9.        routes.MapRoute(

  10.            name: "default",

  11.            template: "{controller=Home}/{action=Index}/{id?}");

  12.    });

  13. }

  这样就使你的应用程序能够处理,程序目录下wwwroot目录的静态文件内容。在我们添加文件缓存之前,我们先要看一下StaticFileMiddleware默认的策略是怎么样的。当第一次加载程序时,浏览器将打开页面并下载所有的资源连接。假如页面没有错误返回都是正确那么就是返回文件数据和Http Status为200 -OK的状态。

 

  然后我们看下这个Http请求对应的Response Header,这里会包含ETagLast-Modified两个值。HTTP内容如下:

  1. HTTP/1.1 200 OK  

  2. Date: Sat, 15 Oct 2016 14:15:52 GMT  

  3. Content-Type: image/svg+xml  

  4. Last-Modified: Sat, 15 Oct 2016 13:43:34 GMT  

  5. Accept-Ranges: bytes  

  6. ETag: "1d226ea1f827703"  

  7. Server: Kestrel  

  如果再次请求这个地址的话,浏览器将发送ETagLast-Modified的值到服务端,如果两个值没有变化,那么服务端会发送304状态到浏览器,那么浏览器将使用之前的资源而不是重新下载一份。

   这样就提高了,浏览器的响应性能,因为文件都缓存到了客户端,并且通过304状态,服务端与浏览器的请求流量得以减少。

  2.设置文件缓存时间

  当然我们都知道如果要设置某一请求的缓存,只需要设置Header为Cache-Control的值。那么在StaticFileMiddleware中间件中,我们怎么设置这个Header呢?

  1. using Microsoft.Net.Http.Headers;

  2.  

  3. app.UseStaticFiles(new StaticFileOptions  

  4. {

  5.    OnPrepareResponse = ctx =>

  6.    {

  7.        const int durationInSeconds = 60 * 60 * 24;

  8.        ctx.Context.Response.Headers[HeaderNames.CacheControl] =

  9.            "public,max-age=" + durationInSeconds;

  10.    }

  11. });

 

  设置后每一个静态文件的请求都会执行这个方法,包括200和304状态的请求;而且在这个例子里浏览器会自动缓存这些文件24小时,但是在此期间并不会返回404状态

  一旦max-age设置的时间过期,浏览器就不会再使用本地缓存,而去直接请求服务器端。这样已经避免了一些额外的请求到服务器端了。如果我们在浏览器与服务器中间使用CDN缓存文件数据的话,这样就算客户端浏览器的缓存过期了,但是请求也不会到我们的服务器上,而是请求到CDN缓存服务器。

  下面我们看看文件缓存在ASP.NET Core中是如何判断缓存失效的?.NET Core开源的代码为我们提供了了解它的入口【代码 Source Code】。核心代码如下:

  1. _length = _fileInfo.Length;

  2. DateTimeOffset last = _fileInfo.LastModified;  

  3. // Truncate to the second.

  4. _lastModified = new DateTimeOffset(last.Year, last.Month, last.Day, last.Hour, last.Minute, last.Second, last.Offset).ToUniversalTime();

  5. long etagHash = _lastModified.ToFileTime() ^ _length;  

  6. _etag = new EntityTagHeaderValue('\"' + Convert.ToString(etagHash, 16) + '\"');

  服务器端如果检测到文件改变就会返回200状态给浏览器,如果没有变化则返回304状态给浏览器端。

  不幸的是,一旦我们添加了缓存,浏览器将不再向服务器发出请求。该文件可能已经完全改变或已被完全删除,但如果浏览器不要求,服务器将不能通知浏览器重新发起无缓存的请求!

  3.为静态文件提供版本号

  通常我们都使用形如https://localhost/js/site.js?v=1 这样的地址来解决缓存的问题。通过给静态文件生成唯一的版本号,做为QueryString进行请求时,服务器将重新输出文件内容。

  在ASP.NET Core中Tag Hepers为我们提供了这样的API:

  1. <script src="~/js/site.js" asp-append-version="true"></script>

  这段代码最终在浏览器端会被渲染为如下Html代码:

  1. <script src="/js/site.js?v=Ynfdc1vuMNOWZfqTj4N3SPcebazoGXiIPgtfE-b2TO4"></script>

  如果静态文件发生改变,Tag Helper就是重新计算文件的哈希值,它采用 SHA256的哈希值。当然以前服务器缓存的文件版本也随之失效了。这个asp-append-version Tag Helper可以支持Img、Script和Link元素。

  ASP.NET Core的源代码我们来看看是怎么计算文件变化的:【源代码 Source Code】 。

 

 三、ASP.NET Core与CDN?

  我们在使用CDN时,因为还要进行开发任务,一般我们都要有两套地址,一套是CDN上的文件地址,一套是本地调试开发用的地址。ASP.NET Core中也为我们提供了Tag Helper来解决这样的问题。直接上代码实例吧:

  1. <link rel="stylesheet" href="//ajax.aspnetcdn.com/ajax/bootstrap/3.0.0/css/bootstrap.min.css"

  2.      asp-fallback-href="~/lib/bootstrap/css/bootstrap.min.css"

  3.      asp-fallback-test-class="hidden"

  4.      asp-fallback-test-property="visibility"

  5.      asp-fallback-test-value="hidden" />

  6.  

  7. <script src="//ajax.aspnetcdn.com/ajax/bootstrap/3.0.0/bootstrap.min.js"

  8.        asp-fallback-src="~/lib/bootstrap/js/bootstrap.min.js"

  9.        asp-fallback-test="window.jQuery">

  10. </script>

  Tag Helper:asp-fallback-* 解决开发时使用的文件地址问题。 当然它也可以asp-append-version 两个Tag Helper一起使用,这样就实现了,在CDN文件缓存的同步问题。

 

四、写在最后

  新的ASP.NET Core为我们提供了很多现有互联网行业的解决方案,也给.NET开发人员引入了先进思想。

原文地址:http://www.cnblogs.com/maxzhang1985/p/6053738.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

阅读原文