You can use if-modified-since with "304 not modified" without PHP

18

Based on this solution used in this answer on SO-en I created a .htaccess and PHP script

.htaccess:

RewriteEngine On

RewriteCond %{HTTP:if-modified-since} .
RewriteCond %{HTTP:if-none-match} .
RewriteRule . not_modified.php [L]

not_modified.php:

<?php
if (isset($_SERVER['REDIRECT_URL'])) {
    $file = $_SERVER['REDIRECT_URL'];
} else if (isset($_SERVER['REQUEST_URI'])) {
    $file = $_SERVER['REQUEST_URI'];
}

$last_modified_time = filemtime($file); 
$etag = md5_file($file);

header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $last_modified_time) . ' GMT'); 

if (
    strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) === $last_modified_time ||
    trim($_SERVER['HTTP_IF_NONE_MATCH']) === $etag
) {
    if (isset($_SERVER['SERVER_PROTOCOL'])) {
        header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
    } else {
        header('HTTP/1.0 304 Not Modified');
    }
}

The script checks for changes to the file and if it does not, then it sends the 304 code to the client response.

My question is the following, is it possible to do this without using PHP, ie using only .htaccess ?

    
asked by anonymous 16.12.2014 / 17:49

1 answer

11

To take advantage of 304 Not Modified you will need to use the module mod_expires and "manipulate" the FileETag rule:

  • mod_expires : Generates HTTP headers Expires and Cache-Control according to user defined criteria
  • FileETag Directive
  • mod_expires

    This module is required to generate cache and use 304 Not Modified , this module works on if-modified-since and if-none-match . A simple example to set the cache in images:

     #Cache de 1 mês a partir da data de acesso do arquivo
    <FilesMatch "\.(?i:ico|gif|jpe?g|png|css|js|svg)$">
       ExpiresDefault "access plus 1 mouth"
    </FilesMatch>
    

    Note that the cache is generated from the date of access of the image.

    FileETag Directive

    When we use Etag instead of if-modified-since it sometimes does not work in an expected way, ie it ignores that there were no "modifications" and sends the file back to the client response. Additionally, according to the "Yahoo! Performance Rules - EN" , disable ETags can make pages loading faster by reducing server load and reducing web page size if your website is on multiple servers.

    Example

    A complete example of .htaccess , note that it was not necessary to use mod_rewrite :

    # Trabalha o if-modified-since com arquivos de estáticos, como images, js, css, etc
    <FilesMatch "\.(?i:ico|gif|jpe?g|png|css|js|svg)$">
        # Cache para um mês
        <IfModule mod_expires.c>
            ExpiresActive On
            ExpiresDefault "access plus 1 mouth"
        </IfModule>
    
        # Remove Etag para previnir o uso do mesmo
        # Pois iremos trabalhar com if-modified-since e last-modifed
        FileETag None
    </FilesMatch>
    

    Read also about:

    16.12.2014 / 19:42