It is possible to use if-modified-Since with "304 not modified" without PHP

Asked

Viewed 1,026 times

18

Based on this solution used in this answer in SO-en i created a . htaccess and a 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 in the file and if there are no changes then it sends the 304 code to the client response.

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

1 answer

11


To use 304 Not Modified for static files it will be necessary to use the module mod_expires and "manipulate" the rule of FileETag:

  1. mod_expires: Generates the HTTP headers Expires and Cache-Control according to criteria defined by the user
  2. Fileetag Directive

mod_expires

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

 #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 image access date.

Fileetag Directive

When we use Etag instead of if-modified-since it sometimes does not work in an expected way, ie ignores that there are no "modifications" and sends the file again to the client response. In addition also according to the "Yahoo! Performance Rules - EN", disable the ETags can make pages load faster by decreasing server load and reducing bandwidth 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:

  • A question, as it was specified the 30 days, if the file is changed before that time.. it will continue to use the cache?

  • Yes @Elaine if the file saved in the person’s computer/browser cache has the same date last amendment then the server does not send the file, it only sends the 304 to reply and the browser generates a new cache with another 30 days for example.

  • I was a little confused. If this server-side file is changed I will get an obsolete file in the next accesses to the site or the new copy will be uploaded?

  • 2

    @Elaine will be loaded when the cache expires, so this goes from file type, you can create a .htaccess for each folder, if it is a folder that has content that changes very often then make a shorter cache time, if it is a folder that rarely content is changed make a larger cache.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.