Web开发中的缓存技术之三:通过ETag实现缓存处理(ASP.NET MVC版)
2010-04-04 21:46
751 查看
IIS已经为我们提供了其内置的缓存功能。但显得比较死板,对于更高的要求,IIS的缓存功能显然就有些不够灵活了。
在mvc风格的开发中我们可以通过Filter来定制缓存方式。
本篇介绍借助ETag响应头实现缓存,没有完美的缓存方案,这种方式能够准确判断客户浏览器缓存是否需要更新,但不会避免服务器再次生成页面的过程,它的主要用意在于避免不必要的数据传输,减少流量缓解带宽压力。
何为ETag,以及Is-Non-Match
您可以把ETag理解为HTTP通信中存在的一个附加信息,服务器产生ETag,客户机浏览器下一次再访问此页面时会在将此值放在Request Headers中的Is-Non-Match里。ETag、Is-Non-Match的一个经典用途就是用于缓存实现。下面会为您详细说明如何通过ETag在ASP.NET MVC中实现缓存处理。
关于ETag,您可以去看看W3C的说明:http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
基本原理
服务器将数据传给客户浏览器前会对页面数据进行哈希计算,并将哈希值转为Base64编码的ASCII字符以存放在Response响应头的ETag信息中。客户机浏览器在接收到来自服务器的信息后会将ETag值缓存到本地,下一次再访问这个页面时就会将此ETag值放在Request头的Is-Non-Match中,服务器仍然会生成页面,但要与此ETag值进行比较,如果相同就说明客户机浏览器中缓存的页面与即将传输的内容一致,进而就不会将重复的页面传输过去而是将状态置为304,这样就减少了不必要的带宽占用。
如何实现
我们要做的是让服务器去接受响应并生成数据,但是在将其写入到流中之前要对即将写入的内容进行检查,看其经过Hash计算的值是否与Is-Non-Match中的值相同,如果相同就将HTTP状态置为304,否则更新ETag并将数据写入到流中。为实现这个目的,我定义了一个包装流,将HttpResponseBase.Filter替换为包装流来方便我们在数据送到客户机之前获得数据。
(说明:asp.net mvc的ActionFilter与java里的那个Filter不太一样,一开始我以为执行到OnResultExecuted时写在response里的内容就已经存在了,后来才发现向Stream里写入数据的过程要在OnResultExecuted之后,于是我只好变相在自定义的ResponseWrapper这个Stream包装流里去处理response。)
效果展示
应用示例
[HandleError]
public class HomeController : Controller
{
[ContentCacheFilter]
//[LazyCacheFilter]
public ActionResult Index()
{
//ViewData["Message"] = DateTime.Now.ToString();
ViewData["Message"] = "this is from asp.net mvc development server";
return View();
}
public ActionResult About()
{
return View();
}
}
ResponseWrapper的实现可能略显不妥,大家有更好的方案希望多多分享哈^^
源码放在skydriver上了,下载页面链接(这是个页面链接迅雷会误认为是文件,刚发现skydriver给的直接下载链接都是带时间戳的,过了一天就不能用了。。。):
http://cid-ebf46737d420f3e0.skydrive.live.com/self.aspx/By%20Sopaco/Sopaco.Lib.Web.Mvc.Filters/Filters.rar
在mvc风格的开发中我们可以通过Filter来定制缓存方式。
本篇介绍借助ETag响应头实现缓存,没有完美的缓存方案,这种方式能够准确判断客户浏览器缓存是否需要更新,但不会避免服务器再次生成页面的过程,它的主要用意在于避免不必要的数据传输,减少流量缓解带宽压力。
何为ETag,以及Is-Non-Match
您可以把ETag理解为HTTP通信中存在的一个附加信息,服务器产生ETag,客户机浏览器下一次再访问此页面时会在将此值放在Request Headers中的Is-Non-Match里。ETag、Is-Non-Match的一个经典用途就是用于缓存实现。下面会为您详细说明如何通过ETag在ASP.NET MVC中实现缓存处理。
关于ETag,您可以去看看W3C的说明:http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
基本原理
服务器将数据传给客户浏览器前会对页面数据进行哈希计算,并将哈希值转为Base64编码的ASCII字符以存放在Response响应头的ETag信息中。客户机浏览器在接收到来自服务器的信息后会将ETag值缓存到本地,下一次再访问这个页面时就会将此ETag值放在Request头的Is-Non-Match中,服务器仍然会生成页面,但要与此ETag值进行比较,如果相同就说明客户机浏览器中缓存的页面与即将传输的内容一致,进而就不会将重复的页面传输过去而是将状态置为304,这样就减少了不必要的带宽占用。
如何实现
我们要做的是让服务器去接受响应并生成数据,但是在将其写入到流中之前要对即将写入的内容进行检查,看其经过Hash计算的值是否与Is-Non-Match中的值相同,如果相同就将HTTP状态置为304,否则更新ETag并将数据写入到流中。为实现这个目的,我定义了一个包装流,将HttpResponseBase.Filter替换为包装流来方便我们在数据送到客户机之前获得数据。
(说明:asp.net mvc的ActionFilter与java里的那个Filter不太一样,一开始我以为执行到OnResultExecuted时写在response里的内容就已经存在了,后来才发现向Stream里写入数据的过程要在OnResultExecuted之后,于是我只好变相在自定义的ResponseWrapper这个Stream包装流里去处理response。)
效果展示
应用示例
[HandleError]
public class HomeController : Controller
{
[ContentCacheFilter]
//[LazyCacheFilter]
public ActionResult Index()
{
//ViewData["Message"] = DateTime.Now.ToString();
ViewData["Message"] = "this is from asp.net mvc development server";
return View();
}
public ActionResult About()
{
return View();
}
}
ResponseWrapper的实现可能略显不妥,大家有更好的方案希望多多分享哈^^
源码放在skydriver上了,下载页面链接(这是个页面链接迅雷会误认为是文件,刚发现skydriver给的直接下载链接都是带时间戳的,过了一天就不能用了。。。):
http://cid-ebf46737d420f3e0.skydrive.live.com/self.aspx/By%20Sopaco/Sopaco.Lib.Web.Mvc.Filters/Filters.rar
相关文章推荐
- [转载]Web开发中的缓存技术:通过ETag实现缓存处理(Asp.Net)
- ASP.NET Web API中通过ETag实现缓存
- YbSoftwareFactory 代码生成插件【十】:ASP.NET WebApi MVC下审计、缓存和导出功能的实现
- 基于.Net Framework 4.0 Web API开发(3):ASP.NET Web APIs 异常的统一处理Attribute 和统一写Log 的Attribute的实现
- asp.net开发中,web页面实现页面元素的多语言化(多国语化)
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十三)[20 Recipes for Programming MVC 3]:实现Ajax增强用户体验
- 通过Asp.Net MVC的区域功能实现将多个MVC项目部署到一个站点
- 在ASP.NET WebForm简单实现伪静态,通过(System.Web.Routing)
- ASP.NET之MVC 微信公众号授权给第三方平台的技术实现流程一(获取第三方平台access_token)
- 通过VML技术 及 XSLT技术实现WEB图形化处理界面.
- dhl:asp.net mvc下用jQuery通过AJAX 实现HTTP 请求加载远程数据
- [asp.netMVC]通过configSource提高web.config配置灵活性
- 基于.Net Framework 4.0 Web API开发(4):ASP.NET Web APIs 基于令牌TOKEN验证的实现
- [翻译]ASP.NET MVC 3 开发的20个秘诀(四)[20 Recipes for Programming MVC 3]:实现多语言支持
- Asp.net Mvc 身份验证、异常处理、权限验证(拦截器)实现代码
- 用ASP.NET 2.0实现AJAX风格的Web开发
- asp.netWeb开发中ztree实现无极限增删改查连接数据同步数据库操作
- 为ASP.NET MVC开发一些常用插件(二)—— 实现无刷新文件上传
- 使用PureMVC实现ASP.NET的MVC结构开发
- ASP.NET MVC 4 Web 编程-Chap02 ASP.NET Web Form 开发人员必读