如何使用浏览器缓存配置ETag

时间:2016-05-16 22:42:40

标签: .htaccess caching browser-cache etag

我通过odd_primes()文件设置了静态网站的浏览器缓存:

.htaccess

我对这些具有1天缓存的图片很好,但网站经常更改,因此我不想缓存CSS和JS文件。

我已经阅读了ETag,据我所知,它允许您缓存文件,但也设置其创建日期,因此如果客户端下次访问该网站时它会更新,它将检查是否创建日期匹配。

  1. 我是否正确理解了ETag?
  2. 如何配置?我环顾四周,但找不到配置信息。

4 个答案:

答案 0 :(得分:5)

您可以使用FileETag MTime SizeHeader unset EtagFileEtag none。不要同时使用(创建ETag和删除ETag),只选择哪一个最适合您的特定服务器。

# Create the ETag (entity tag) response header field
FileETag MTime Size

# Remove the ETag (entity tag) response header field
Header unset ETag
FileETag none

答案 1 :(得分:3)

ETAG不是最重要的属性。您缺少的主要属性是过期。我百分之百确定,浏览器缓存无需etag即可运行。检查http://pisrs.si上的以下配置。怎么检查?在浏览器中点击F12,转到网络标签,查看如何获取资源,与您的网站进行比较。 Localhost资源以不同方式缓存。检查您的浏览器信息。

以下是来自主域的工作配置,即工作正常。确保已启用必要的mod。

<IfModule mod_mime.c>
    AddType text/css .css
    AddType application/x-javascript .js
    AddType image/bmp .bmp
    AddType image/gif .gif
    AddType application/x-gzip .gz .gzip
    AddType image/x-icon .ico
    AddType image/jpeg .jpg .jpeg .jpe
    AddType image/png .png
    AddType application/x-font-ttf .ttf .ttc
    AddType application/zip .zip
</IfModule>
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType text/css A31536000
    ExpiresByType application/x-javascript A31536000
    ExpiresByType application/javascript A31536000
    ExpiresByType text/javascript A31536000
    ExpiresByType text/x-js A31536000
    ExpiresByType image/bmp A31536000
    ExpiresByType image/gif A31536000
    ExpiresByType application/x-gzip A31536000
    ExpiresByType image/x-icon A31536000
    ExpiresByType image/jpeg A31536000
    ExpiresByType application/x-font-otf A31536000
    ExpiresByType image/png A31536000
    ExpiresByType application/x-font-ttf A31536000
    ExpiresByType application/zip A31536000
</IfModule>
<IfModule mod_deflate.c>
    <IfModule mod_headers.c>
        Header append Vary User-Agent env=!dont-vary
    </IfModule>
        AddOutputFilterByType DEFLATE text/html text/css text/x-component application/x-javascript application/javascript text/javascript text/x-js text/plain image/x-icon image/png image/gif
    <IfModule mod_mime.c>
        # DEFLATE by extension
        AddOutputFilter DEFLATE js css htm html xml png gif
    </IfModule>
</IfModule>
<FilesMatch "\.(gif|ico|jpg|jpeg|png|GIF|ICO|JPG|JPEG|PNG|css|js|woff|CSS|JS|WOFF|ttf|TTF)$">
    <IfModule mod_headers.c>
         Header unset Set-Cookie
         Header set Cache-Control "max-age=31536000, public"
    </IfModule>
</FilesMatch>

答案 2 :(得分:2)

ETag只是一个独特的不透明标记,除了相等之外,您无法对它们进行比较,因此如果您对同一资源(例如URI)有2个ETag,则无法判断哪个资源更新。为此,您需要Last-Modified标头。

即使是Last-Modified标头也存在问题,因为它的分辨率只有1秒,而且在经过大量修改的网站(如热门博客)上,缓存很可能有多个文件表示形式。不同的ETag和相同的Last-Modified值。遗憾的是,他们认为不适合使ETag单调递增,因此可以对它们进行比较。

ETag用于带有GET的If-None-Match标头和PUT的If-Match的条件请求,并且在第一种情况下,只有当提供的ETag都不匹配时,服务器才应返回完整的主体资源的当前ETag(已更改),以及第二种情况(对于PUT或PATCH),只有当它匹配时,才能使用正确的版本。

但ETag和Last-Modified都是缓存验证器标头。缓存的大部分好处都与新鲜度的概念有关。验证程序允许您检查您的版本是否仍然有效,但仍需要向服务器发出请求。你可以节省的只是有效载荷转移,对于现在的许多事情来说,它是不值得的。

另一方面,新鲜度(Expires header或max-age Cache-Control指令)允许客户端避免重新验证,如果他们已经是新鲜的版本(没有过期)。这节省了连接到服务器以进行检查,因此可以节省大量的页面加载时间。

答案 3 :(得分:0)

HTTP有几个features related to caching,它们同时适用于用户代理(浏览器)缓存和代理缓存(无论是否透明;例如客户端网络中的代理或位于服务器旁边的反向代理)。这些功能分为两组:expiration(可能完全阻止请求)和validation(可能会阻止数据传输)。

Entity tagETag)只是其中一项功能,属于验证组。该组中的另一个是上次修改时间(Last-Modified)。 实体标记允许因内容更改而导致缓存失效,而不是更新的上次修改时间。在维基百科上的how entity tag works上阅读更多内容。简而言之,典型的用法是:

  1. 服务器将ETag标头添加到包含所投放资源的响应中。

  2. 客户端缓存资源并记住其实体标记(ETag的值)。

  3. 下次客户端需要资源时,它会从服务器有条件地请求它。在请求中,它包含If-None-Match包含实体标记的标头。

  4. 如果资源发生变化(服务器认为If-None-Match中的实体标签已过时),服务器会发送包含资源当前版本(和新实体标签)的响应,否则它只会响应304 Not Modified并且不再费心再次发送资源。

  5. 对于静态文件(也不是由每个请求的CGI脚本动态创建),Apache可以配置为通过FileETag directive生成ETag默认情况下,如果不对配置进行任何更改, Apache将生成ETag ,其值将基于文件的上次修改时间(mtime)和Apache 2.4中的大小。在Apache 2.3.14中,默认用于包含文件的inode编号。

    如果文件是动态提供的,则Apache无法生成ETag,因为它不知道如何生成要缓存的资源的详细信息。脚本可以适当地设置ETag并处理If-None-Match。例如。在mod_perl中,If-None-Match部分可以使用Apache2::Request::meets_conditions来处理,HTTP/1.1 advises against that, in general通常会实现HTTP / 1.1条件请求的处理。

    如果您只想依赖ETag ,则必须禁用其他验证功能和过期机制。设置Cache-Control: max-age=0, must-revalidateExpires: 0以强制重新验证缓存条目(即始终发出请求)。您也可以从回复中删除Last-Modified标题,但if-modified-since vs if-none-match @ SO

    有关Last-ModifiedETag的比较,请参阅以下内容:

    请注意RFC 7232ETag可能包含相同的值且工作方式完全相同(使用If-None-Match代替If-Modified-Since除外)。

    作为旁注,我想补充一点,建议的标准changes it introduces from HTTP/1.1存在,它与实体标签和条件请求的细节有关。请参阅{{3}}的附录A.