ahjesus 前端缓存原理

ahjesus 前端缓存原理

LAMP缓存图

从图中我们可以看到网站缓存主要分为五部分

服务器缓存:主要是基于web反向代理的静态服务器nginx和squid,还有apache2的mod_proxy和mod_cache模

浏览器缓存:包括页面html缓存和图片js,css等资源的缓存

PHP缓存:有很多免费的PHP缓冲加速工具,如apc eaccerlertor等

内存缓存:主要是采用memcache这种分布式缓存机制

数据库缓存:通过配置数据库缓存,以及数据存储过程,连接池技术等

下面重点介绍浏览器缓存原理:

ahjesus 前端缓存原理

从上图:我们可以知道浏览器缓存重要分为两个部分:

页面html的缓存图片,css,js,flash等缓存浏览器缓存是基于把页面信息保存到用户本地电脑硬盘里。

服务器缓存是基于把用户访问的页面保存到服务器上的硬盘里。

页面缓存的原理

页面缓存状态是由http header决定的,一个浏览器请求信息,一个是服务器响应信息。主要包括Pragma: no-cache、Cache-Control、 Expires、 Last-Modified、If-Modified-Since。其中Pragma: no-cache由HTTP/1.0规定,Cache-Control由HTTP/1.1规定。

ahjesus 前端缓存原理

从图中我们可以看到原理主要分三步:

第一次请求:浏览器通过http的header报头,附带Expires,Cache-Control,Last-Modified/Etag向服务器请求,此时服务器记录第一次请求的Last-Modified/Etag再次请求:

当浏览器再次请求的时候,附带Expires,Cache-Control,If-Modified-Since/Etag向服务器请求

服务器根据第一次记录的Last-Modified/Etag和再次请求的If-Modified-Since/Etag做对比,判断是否需要更新,然后响应请求。

相关参数说明:

Cache-Control的主要参数 Cache-Control: private/public Public 响应会被缓存,并且在多用户间共享。 Private 响应只能够作为私有的缓存,不能再用户间共享。

Cache-Control: no-cache:不进行缓存

Cache-Control: max-age=x:缓存时间 以秒为单位

Cache-Control: must-revalidate:如果页面是过期的 则去服务器进行获取。

Expires:显示的设置页面过期时间

Last-Modified:请求对象最后一次的修改时间 用来判断缓存是否过期 通常由服务器上文件的时间信息产生。

If-Modified-Since :客户端发送请求附带的信息 指浏览器缓存请求对象的最后修改日期 用来和服务器端的Last-Modified做比较。

Etag:ETag是一个可以 与Web资源关联的记号(token),和Last-Modified功能才不多,也是一个标识符,一般和Last-Modified一起使用,加强服务器判断的准确度。

 

转载自 http://www.vicenteforever.com/2012/05/web-front-cache/

 

 

附代码:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Web;

using System.Configuration;



namespace __System.Web

{

    public class MyHttpModule : IHttpModule

    {

        public void Dispose()

        {



        }



        public void Init(HttpApplication context)

        {

            context.BeginRequest += new EventHandler(context_BeginRequest);

            context.EndRequest += new EventHandler(context_EndRequest);

        }



        void context_EndRequest(object sender, EventArgs e)

        {

            ChangeCache(sender);

        }



        void context_BeginRequest(object sender, EventArgs e)

        {

            //HttpApplication application = (HttpApplication)sender;

            //HttpContext context = application.Context;

            //string filePath = context.Request.FilePath;

            //string fileExtension = VirtualPathUtility.GetExtension(filePath);

            //if (fileExtension.Equals(".html") || fileExtension.Equals(".htm"))

            //{

            //    context.Response.Write("<hr><h1><font color=red>" +

            //        "HelloWorldModule: End of Request</font></h1>");

            //}



        }



        void ChangeCache(object sender)

        {

            HttpApplication application = (HttpApplication)sender;

            HttpResponse response = application.Context.Response;



            string ex = ConfigurationManager.AppSettings["WebCacheExpires"];

            int expires = string.IsNullOrEmpty(ex) ? 5 : Convert.ToInt32(ex);



            //设置Expires为当前日期再加上60秒

            response.Cache.SetExpires(DateTime.Now.AddSeconds(60 * expires));

            //HttpCacheability枚举类型会找个时间解释下 

            //HttpCacheability. Public 指定响应能由客户端和共享(代理)缓存进行缓存

            response.Cache.SetCacheability(HttpCacheability.Public);

            response.Cache.SetValidUntilExpires(true);

        }

        void Filter(object sender)

        {

            HttpApplication application = (HttpApplication)sender;

            HttpContext context = application.Context;

            int statusCode = context.Response.StatusCode;

            if (statusCode==200)

            {

                string filePath = context.Request.FilePath;

                string fileExtension = VirtualPathUtility.GetExtension(filePath);

                if (fileExtension.Equals(".html") || fileExtension.Equals(".htm") || fileExtension.IndexOf(".") > 0)

                {

                    //判断缓存是否存在,不存在加入缓存,调用生成静态的类和方法  

                    //产品过期,移除静态文件,302重定向  

                    //if (System.IO.File.Exists(context.Server.MapPath(filePath)))

                    //{

                    //    context.Response.WriteFile(context.Server.MapPath(filePath));

                    //    context.Response.End();

                    //}

                }

            }            

        }

    }

}
View Code

 

你可能感兴趣的:(前端)