0

如何cache为通过 json.php 重写/生成的 test.json 启用浏览器?
不幸的是 test.json 响应为\.php$而不是设置的标头\.json$

如何正确应用 .htaccess 规则,以便 json.php 生成的 test.json 将被缓存并在浏览器刷新时返回304 Not Modified?为什么Server: Apache我使用时仍然显示响应标头ServerSignature Off

test.json 停留在 status 200 OK,响应标头:

Date                    Thu, 17 Feb 2011 10:24:44 GMT
Server                  Apache
Content-Encoding        gzip
Vary                    Accept-Encoding
X-Content-Type-Options  nosniff
Cache-Control           private, max-age=0
Imagetoolbar            no
Content-Length          88
Keep-Alive              timeout=1, max=100
Connection              Keep-Alive
Content-Type            application/json; charset=UTF-8

json.php

<?php
    header('Content-type: application/json; charset=UTF-8');
    echo '{"tets":"json"}';
?>

httpd.conf

ServerTokens Prod
KeepAliveTimeout 1

.htaccess

Options -Indexes +FollowSymLinks -MultiViews
ServerSignature Off
php_value output_handler ob_gzhandler
AddType application/json .json
AddDefaultCharset utf-8
AddCharset utf-8 .json
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE application/x-httpd-php application/json
    <IfModule mod_setenvif.c>
        BrowserMatch ^Mozilla/4 gzip-only-text/html
        BrowserMatch ^Mozilla/4\.0[678] no-gzip
        BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    </IfModule>
</IfModule>
<IfModule mod_gzip.c>
    mod_gzip_on Yes
    mod_gzip_can_negotiate Yes
    mod_gzip_static_suffix .gz
    AddEncoding gzip .gz
    mod_gzip_update_static No
    mod_gzip_keep_workfiles No
    mod_gzip_minimum_file_size 500
    mod_gzip_maximum_file_size 5000000
    mod_gzip_maximum_inmem_size 60000
    mod_gzip_min_http 1000
    mod_gzip_dechunk Yes
    mod_gzip_handle_methods GET POST
    mod_gzip_item_include file \.(php|json)$
    mod_gzip_item_include mime ^application/x-httpd-php$
    mod_gzip_item_include mime ^application/json$
    mod_gzip_item_include mime ^httpd/unix-directory$
    mod_gzip_item_include handler ^proxy-server$
    mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
    mod_gzip_send_vary On
</IfModule>
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresDefault "access plus 1 month"
    ExpiresByType application/x-httpd-php "access plus 0 second"
    ExpiresByType application/json "access plus 1 day"
</IfModule>
<IfModule mod_headers.c>
    <FilesMatch "\.php$">
        Header set Cache-Control "private, max-age=0"
        Header set Imagetoolbar no
    </FilesMatch>
    <FilesMatch "\.json$">
        Header set Cache-Control "public, max-age=31536000"
        Header append Vary Accept-Encoding
    </FilesMatch>
    FileETag None
    Header unset ETag
    Header unset X-Powered-By
    Header set X-Content-Type-Options: nosniff
</IfModule>
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^test.json json.php [L,QSA]
</IfModule>
4

2 回答 2

2

要启用 chaching,请添加以下内容:

ExpiresDefault "access plus 1 month"

要防止缓存,请执行以下操作:

根据http://www.askapache.com/htaccess/using-http-headers-with-htaccess.html#prevent-caching-with-htaccess,添加这个

<FilesMatch "\.json$">
  FileETag None
  <IfModule mod_headers.c>
    Header unset ETag
    Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
  </IfModule>
</FilesMatch>
于 2011-02-17T11:37:32.750 回答
0

感谢@Rich Bradshaw,我在Answering HTTP_IF_MODIFIED_SINCE 和 HTTP_IF_NONE_MATCH in PHP中找到了使用 PHP 标头的解决方案

function caching_headers($file,$timestamp){
    $gmt_mtime=gmdate('r', $timestamp);
    header('ETag: "'.md5($timestamp.$file).'"');
    if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])||isset($_SERVER['HTTP_IF_NONE_MATCH'])){
        if ($_SERVER['HTTP_IF_MODIFIED_SINCE']==$gmt_mtime||str_replace('"','',stripslashes($_SERVER['HTTP_IF_NONE_MATCH']))==md5($timestamp.$file)){
            header('HTTP/1.1 304 Not Modified');
            exit();
        }
    }
    header('Last-Modified: '.$gmt_mtime);
    header('Cache-Control: public');
}
caching_headers($_SERVER['SCRIPT_FILENAME'],filemtime($_SERVER['SCRIPT_FILENAME']));

可能没有更好/合适的解决方案。

于 2011-02-17T22:31:57.960 回答