zoukankan      html  css  js  c++  java
  • Apache静态资源缓存配置

    1、缓存机制了解

    ExpiresCache-ControlLast-ModifiedETag 是和网页缓存相关的几个字段。在看如何设置之前,我们先了解一下这几个字段的作用。

    1.1 强制缓存

    强制缓存的含义是,当客户端请求后,会先访问缓存数据库看缓存是否存在。如果存在则直接返回;不存在则请求真的服务器,响应后再写入缓存数据库。

    ● Expires

    这是 HTTP 1.0 的字段,用来指定资源到期的时间,是服务器端的具体的时间点。表示缓存到期时间,是一个绝对的时间 (当前时间+缓存时间),如

    Expires: Thu, 10 Nov 2017 08:45:11 GMT
    

    在响应消息头中设置这个字段之后,就可以告诉浏览器在未过期之前不需要再次请求。但是如果修改了本地时间,可能会造成缓存失效。

    ● Cache-control

    HTTP/1.1中,增加了一个字段Cache-control,该字段表示资源缓存的最大有效时间,在该时间内,客户端不需要向服务器发送请求。
    ExpiresCache-control的区别就是前者是绝对时间,而后者是相对时间。如下:

    Cache-control: max-age=2592000
    

    下面列举一些 Cache-control 字段常用的值:

    no-cache:虽然字面意思是“不要缓存”,但实际上还是要求客户端缓存内容的,只是是否使用缓存则需要经过协商缓存来验证决定。

    no-store: 真正意义上的“不要缓存”。所有内容都不走缓存,即不使用强制缓存,也不使用协商缓存。

    public:所有的内容都可以被缓存 (包括客户端和代理服务器, 如 CDN)。

    private:所有的内容只有客户端才可以缓存,中间节点不允许缓存,例如代理服务器。Cache-Control的默认值。

    max-age:即最大有效时间,表示缓存内容将在xxx秒后失效。

    must-revalidate:如果超过了 max-age 的时间,浏览器必须向服务器发送请求,验证资源是否还有效。

    Cache-control 的优先级高于 Expires,为了兼容 HTTP/1.0 和 HTTP/1.1,实际项目中两个字段我们都会设置。

    1.2 协商缓存

    协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。

    ● Last-Modified & If-Modified-Since

    浏览器在第一次访问资源时,服务器返回资源的同时,在response header中添加 Last-Modified字段,告知浏览器资源最后一次被修改的时间,例如
    Last-Modified: Fri, 22 Jul 2016 01:47:00 GMT
    浏览器将这个值和内容一起记录在浏览器缓存中。浏览器下一次请求这个资源,浏览器检测到有 Last-Modified这个header,于是添加If-Modified-Since这个header,值就是Last-Modified中的值;服务器再次收到这个资源请求,会根据 If-Modified-Since 中的值与服务器中这个资源的最后修改时间对比,如果没有变化,返回304和空的响应体,直接从缓存读取,如果If-Modified-Since的时间小于服务器中这个资源的最后修改时间,说明文件有更新,于是返回新的资源文件和200。

    缺点:

    • 如果资源更新的速度是秒以下单位,那么该缓存是不能被使用的,因为它的时间单位最低是秒。
    • 如果文件是通过服务器动态生成的,那么该方法的更新时间永远是生成的时间,尽管文件可能没有变化,所以起不到缓存的作用。
    ● Etag & If-None-Match

    为了解决上述问题,出现了一组新的字段 EtagIf-None-Match
    Etag 存储的是文件的特殊标识(一般都是 hash 生成的),服务器存储着文件的 Etag 字段。之后的流程和 Last-Modified 一致,只是 Last-Modified 字段和它所表示的更新时间改变成了 Etag 字段和它所表示的文件 hash,把 If-Modified-Since 变成了 If-None-Match。服务器同样进行比较,命中返回 304, 不命中返回新资源和 200。

    Etag 的优先级高于 Last-Modified

    更多关于缓存知识请查看:

    深入理解浏览器的缓存机制

    一文读懂前端缓存

    2. Apache缓存配置例子

    对于一般的纯静态页面,如html、gif、jpg、css、js,默认安装的Apache服务器,不会在响应头添加这个字段。在Apache的配置文件中进行静态资源配置即可,这里我用的是Apache2.4版本。

    2.1 Apache设置Express

    使用Apachemod_expires.so 模块来设置,这包括控制应答时的Expires头内容和Cache-Control头的max-age指令

    启用expires_module模块:

    a2enmod expires
    

    重启Apache

    server apache2 reload
    

    修改apache2.conf文件:

    # 启用有效期控制
    ExpiresActive On
    # 图片
    ExpiresByType image/jpg "access plus 1 month" 
    ExpiresByType image/jpeg "access plus 1 month"
    ExpiresByType image/gif "access plus 1 month"
    ExpiresByType image/png "access plus 1 month"
    ExpiresByType image/x-icon "access plus 1 month"
    # css/js
    ExpiresByType text/css "access plus 4 weeks"
    ExpiresByType text/javascript "access plus 4 weeks"
    # html
    ExpiresByType text/html "access plus 2 days"
    

    或者

    <ifmodule mod_expires.c>
    # image
    <filesmatch ".(jpg|jpeg|gif|png|ico)$">
    ExpiresActive on
    ExpiresDefault "access plus 1 month "
    </filesmatch>
    # css/js
    <filesmatch ".(css|js)$">
    ExpiresActive on
    ExpiresDefault "access plus 4 weeks "
    </filesmatch>
    # html
    ExpiresByType text/html "access plus 2 days"
    </ifmodule>
    

    注:当设置了expires后,在response header会自动输出Cache-Control 的max-age 信息

    2.2 Apache设置Cache-Control

    启用 headers_module 模块

    a2enmod headers
    

    重启 Apache

    server apache2 reload
    

    修改apache2.conf文件:

    # 配置mod_headers模块
    <FilesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|woff|js|css|swf)$">
    	Header set Cache-Control "max-age=604800"
    </FilesMatch>
    

    2.3 Apache设置Last-Modified

    一般纯静态页面本身都会有Last-Modified信息,Apache服务器会读取页面文件中的Last-Modified信息,并添加到http响应头部。
    对于动态页面,如果在页面内部没有通过函数强制加上Last-Modified,例如

    header(”Last-Modified: ” . gmdate(”D, d M Y H:i:s”) . ” GMT”)
    

    Apache服务器会把当前时间作为Last-Modified,返回给浏览器。

    2.4 Apache设置Etag

    Apache中设置Etag的支持比较简单,可以通过FileETag指令配置该选项, 例如在Apache配置文件里面加入:

    FileETag MTime Size // 大小(Size)和最后修改时间(MTime)进行Hash后得到文件的ETag的值
    FileETag None // 可以使响应头不再包含ETag字段
    

    3.完整例子

    <VirtualHost *:80>
    ServerName www.xxxx.com
    DocumentRoot /xx/xxx/
    # 配置mod_expires模块
    # 启用有效期控制
    ExpiresActive On
    # image
    ExpiresByType image/jpg "access plus 1 month" 
    ExpiresByType image/jpeg "access plus 1 month"
    ExpiresByType image/gif "access plus 1 month"
    ExpiresByType image/png "access plus 1 month"
    ExpiresByType image/x-icon "access plus 1 month"
    # css/js
    ExpiresByType text/css "access plus 4 weeks"
    ExpiresByType text/javascript "access plus 4 weeks"
    # html
    ExpiresByType text/html "access plus 2 days"
    # 配置mod_headers模块
    <FilesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|woff|js|css|swf)$">
    Header set Cache-Control "max-age=604800"
    FileETag MTime Size
    </FilesMatch>
    <VirtualHost>
    
  • 相关阅读:
    svn环境搭建
    Svn正确的使用方法
    基于phpExcel写的excel类
    关于ecshop中jquery与js冲突解决的方案
    学习Javascript闭包(Closure)
    JS全局变量VAR和THIS
    python六十六课——单元测试(二)
    python六十五课——单元测试(一)
    python六十四课——高阶函数练习题(三)
    python六十四课——高阶函数练习题(二)
  • 原文地址:https://www.cnblogs.com/huiguo/p/12701107.html
Copyright © 2011-2022 走看看