zoukankan      html  css  js  c++  java
  • 缓存篇(Cache)~第三回 HttpModule实现网页的文件级缓存

    返回目录

    再写完缓存篇第一回之后,得到了很多朋友的好评和来信,所以,决定加快步伐,尽快把剩下的文章写完,本篇是第三回,主要介绍使用HttpModule实现的文件级缓存,在看本文之前,大家需要限度HttpModule有一个了解,可以先看我的这篇文章《开发人员应该对IIS理论层的知识了解的多一些~第四讲 HttpModule中的几大事件》

    对于文件级缓存来说,我们要知道两点,一为文件的URL,二为文件的

    下面是HttpModuleCache的核心代码

    /// <summary>
        /// CacheHttpModule类
        /// </summary>
        internal class CacheHttpModule : IHttpModule
        {
            public void Dispose()
            {
            }
            private List<string> listNeedCacheExtend;
            private string stringClearCache = "zzl";//域名中第一段 url 如果是此字符,则表示此次请求是清除缓存 如: http://www.domain.com/zzl/*******
            public void Init(HttpApplication context)
            {
                context.BeginRequest += new EventHandler(context_BeginRequest);
                context.ReleaseRequestState += new EventHandler(context_ReleaseRequestState);
    
                listNeedCacheExtend = new List<string>();
                string extends = WebConfig.GetUserSection("CacheInfo", "ExtendTypes", ".html|.htm");
                foreach (string s in extends.Split('|'))
                {
                    if (!string.IsNullOrEmpty(s) && !listNeedCacheExtend.Contains(s.Trim()))
                        listNeedCacheExtend.Add(s.Trim());
                }
    
            }
    
            public void context_BeginRequest(object sender, EventArgs e)
            {
                var application = (HttpApplication)sender;
    
                if (IsNeedCache(application)) //检测当前请求是否需缓存
                {
                    string key = string.Empty; ;
                    string extend = VirtualPathUtility.GetExtension(application.Context.Request.FilePath).ToLower();
                    if (IsClearCache(application, out key))
                    {
                        if (CacheManage.Container(key, extend))//缓存中存在,则清除缓存,结束请求
                        {
                            application.Context.Response.Write(CacheManage.Remove(key, extend));
                        }
                        application.CompleteRequest();
                    }
                    else
                    {
                        #region 使用页面压缩
    
                        ResponseCompressionType compressionType = this.GetCompressionMode(application.Context.Request);
                        if (compressionType != ResponseCompressionType.None)
                        {
                            application.Context.Response.AppendHeader("Content-Encoding", compressionType.ToString().ToLower());
                            if (compressionType == ResponseCompressionType.GZip)
                            {
                                application.Context.Response.Filter = new GZipStream(application.Context.Response.Filter, CompressionMode.Compress);
                            }
                            else
                            {
                                application.Context.Response.Filter = new DeflateStream(application.Context.Response.Filter, CompressionMode.Compress);
                            }
                        }
    
                        #endregion
                        if (CacheManage.Container(key, extend))//缓存中存在,则直接返回内容,结束请求
                        {
                            CacheManage.Write(application, key);
                            application.CompleteRequest();
                        }
                    }
    
    
    
                }
            }
    
            /// <summary>
            /// 检测当前请求是否需缓存,如果是则将此次结果添加至缓存,如果此次请求出错,不会执行至此
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            public void context_ReleaseRequestState(object sender, EventArgs e)
            {
                var application = (HttpApplication)sender;
                if (application.Context.Response.StatusCode == 200)
                {
                    string strT = null;
                    string extend = VirtualPathUtility.GetExtension(application.Context.Request.FilePath).ToLower();
                    if (IsNeedCache(application) && !IsClearCache(application, out strT))
                    {
                        string key = application.Context.Request.Url.AbsoluteUri;
                        //是否需要添加缓存,
                        if (!CacheManage.Container(key, extend))
                        {
                            application.Context.Response.Filter = new ResponseFilter(application.Context.Response.Filter, key, extend, application.Context.Response.ContentEncoding);
                        }
                    }
                }
            }
    
            public void context_EndRequest(object sender, EventArgs e)
            {
                var application = (HttpApplication)sender;
                string key = application.Context.Request.Url.AbsoluteUri;
                application.Context.Response.Write("<Br>CacheMdule EndRequest");
            }
    
            /// <summary>
            /// 检测当前请求类型(url扩展名)确定是否需缓存
            /// 如果类型需缓存,但扩展名是html或htm且存在相对应的物理文件的,不执行缓存操作
            /// </summary>
            /// <param name="strFilePath"></param>
            /// <returns></returns>
            private bool IsNeedCache(HttpApplication application)
            {
                bool boolNeedCache = false;
                string stringExtend = VirtualPathUtility.GetExtension(application.Context.Request.FilePath).ToLower();
                if (null != listNeedCacheExtend) //url扩展名是否满足条件
                {
                    boolNeedCache = listNeedCacheExtend.Contains(stringExtend);
                }
    
                if (boolNeedCache)
                {
                    if (stringExtend == ".html" || stringExtend == ".htm")
                    {
                        if (System.IO.File.Exists(application.Context.Request.PhysicalPath)) //存在对应物理文件
                        {
                            boolNeedCache = false;
                        }
                    }
                }
                return boolNeedCache;
            }
    
            /// <summary>
            /// 检测当次请求是否是清除缓存的 
            /// True 清除缓存  False  不是清除缓存的
            /// </summary>
            /// <param name="application"></param>
            /// <param name="url">真实的URL地址</param>
            /// <returns></returns>
            private bool IsClearCache(HttpApplication application, out string url)
            {
                bool boolClearCache = false;
                url = application.Context.Request.Url.AbsoluteUri;
                string domain = application.Context.Request.Url.Host;
                Regex regex = new Regex("http://" + domain + "/" + stringClearCache + "/", RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
                if (regex.IsMatch(url))
                {
                    boolClearCache = true;
                    url = "http://" + domain + "/" + url.Replace(regex.Match(url).Captures[0].Value, string.Empty);
                }
                return boolClearCache;
            }
    
    
            /// <summary>
            /// 获取客户端支持的压缩类型
            /// </summary>
            /// <param name="request"></param>
            /// <returns></returns>
            private ResponseCompressionType GetCompressionMode(System.Web.HttpRequest request)
            {
                string acceptEncoding = request.Headers["Accept-Encoding"];
                if (string.IsNullOrEmpty(acceptEncoding))
                    return ResponseCompressionType.None;
    
                acceptEncoding = acceptEncoding.ToUpperInvariant();
                if (acceptEncoding.Contains("GZIP"))
                    return ResponseCompressionType.GZip;
                else if (acceptEncoding.Contains("DEFLATE"))
                    return ResponseCompressionType.Deflate;
                else
                    return ResponseCompressionType.None;
            }
    
            private enum ResponseCompressionType
            {
                None, GZip, Deflate
            }
    
        }

    对于上面的HttpModule来说,还需要在config文件中进行相应的配置,代码如下

      <modules runAllManagedModulesForAllRequests="true" >
          <add name="CacheHttpModule" type="HttpModuleCache.CacheHttpModule,HttpModuleCache"/>
        </modules>

    程序运行后当检测到合法的文件后(如你之前对html和shtml结尾的文件进行缓存),就会生成文件到服务器的指定位置,下次访问时,直接通过URL生成的服务器本地路径,将静态文件返回到客户端即可,不过,有个地方要注意,由于这种方法生成的缓存文件,它的位置不是固定的,所以,在引用CSS,JS这种文件时,要用绝对路径的形式。

    没有用绝对路径时

    用了绝对路径后

    怎么样,这种文件级缓存的方式大家都掌握了吧!

    下载完整HttpModuleCache项目

    返回目录

  • 相关阅读:
    AngularJS各种'service'的区别
    js 斐波那契数列实现
    Mac下Apache+MySQL+PHP开发环境安装过程
    原生封装的js前端工具库(包含了jquery的常用功能)
    BFC 神奇背后的原理
    CSS清浮动处理(Clear与BFC)
    JavaScript实现 页面滚动图片加载(懒加载)
    CodeForce 814B
    排序算法
    uva1610
  • 原文地址:https://www.cnblogs.com/lori/p/4012823.html
Copyright © 2011-2022 走看看