0

How to enable browser cache for test.json that has rewrite/is generated trough json.php ?
Unfortunately test.json responds headers that are set for \.php$ and not \.json$.

How to applay .htaccess rules correctly, so that test.json that is generated by json.php will be cached and on browser refresh it'll return 304 Not Modified? And why response header still shows Server: Apache when I use ServerSignature Off?

test.json stuck on status 200 OK, response headers:

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>
Binyamin
  • 7,493
  • 10
  • 60
  • 82

2 Answers2

2

To enable chaching add this:

ExpiresDefault "access plus 1 month"

To prevent caching do this:

According to http://www.askapache.com/htaccess/using-http-headers-with-htaccess.html#prevent-caching-with-htaccess, add this

<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>
powtac
  • 40,542
  • 28
  • 115
  • 170
  • I am asking - how to enable browser cache for json.php `application/json` and prevent caching *.php `application/x-httpd-php` – Binyamin Feb 17 '11 at 12:59
0

Thanks @Rich Bradshaw, I found the solution on using PHP header in Answering HTTP_IF_MODIFIED_SINCE and HTTP_IF_NONE_MATCH in 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']));

Probably there are no better/suitable solution.

Community
  • 1
  • 1
Binyamin
  • 7,493
  • 10
  • 60
  • 82